You may wonder why the mov  instruction does not include the shift forms that you have seen in most other instructions. Actually, you could use a mov instruction and follow the pattern used for other instructions (for example, add ), but because shifts are so commonly used, the ARM instruction set provides specific shift instructions. Using either a shift instruction or a mov with the corresponding shift options will produce the same machine code. But the explicit shift instructions are considered standard usage.

ASR

Arithmetic Shift Right.

ASR{S}{<c>}   {<Rd>,} <Rn>, #<const>       % immediate
ASR{S}{<c>}   {<Rd>,} <Rn>, <Rm>           % register
• If ‘S’ is present the condition flags are updated according to the result. If absent, the condition flags are not changed.

• <c> is the condition code, Table 9.2.1.

• <Rd> specifies the destination register, <Rn> is the source register, and <Rm> is the shift register.

• $1 \le const \le 32\text{.}$

All 32 bits in the <Rn> register are shifted right, copying the sign bit into the high-order bit positions. The amount of shift is <const> in the “immediate” form or the value in <Rm> in the “register” form. If <Rd> is absent, the result is stored in <Rn>. If <Rd> is present, the result is stored there and <Rn> remains unchanged.

LSR

Logical Shift Right.

LSR{S}{<c>}   {<Rd>,} <Rn>, #<const>       % immediate
LSR{S}{<c>}   {<Rd>,} <Rn>, <Rm>           % register
• If ‘S’ is present the condition flags are updated according to the result. If absent, the condition flags are not changed.

• <c> is the condition code, Table 9.2.1.

• <Rd> specifies the destination register, <Rn> is the source register, and <Rm> is the shift register.

• $1 \le const \le 32\text{.}$

All 32 bits in the <Rn> register are shifted right, storing zeros in the vacated high-order bit positions. The amount of shift is <const> in the “immediate” form or the value in <Rm> in the “register” form. If <Rd> is absent, the result is stored in <Rn>. If <Rd> is present, the result is stored there and <Rn> remains unchanged.

LSL

Logical Shift Left.

LSL{S}{<c>}   {<Rd>,} <Rn>, #<const>       % immediate
LSL{S}{<c>}   {<Rd>,} <Rn>, <Rm>           % register
• If ‘S’ is present the condition flags are updated according to the result. If absent, the condition flags are not changed.

• <c> is the condition code, Table 9.2.1.

• <Rd> specifies the destination register, <Rn> is the source register, and <Rm> is the shift register.

• $1 \le const \le 32\text{.}$

All 32 bits in the <Rn> register are shifted left, storing zeros in the vacated low-order bit positions. The amount of shift is <const> in the “immediate” form or the value in <Rm> in the “register” form. If <Rd> is absent, the result is stored in <Rn>. If <Rd> is present, the result is stored there and <Rn> remains unchanged.

ROR

Rotate Right.

ROR{S}{<c>}   {<Rd>,} <Rn>, #<const>       % immediate
ROR{S}{<c>}   {<Rd>,} <Rn>, <Rm>           % register
• If ‘S’ is present the condition flags are updated according to the result. If absent, the condition flags are not changed.

• <c> is the condition code, Table 9.2.1.

• <Rd> specifies the destination register, <Rn> is the source register, and <Rm> is the shift register.

• $1 \le const \le 32\text{.}$

All 32 bits in the <Rn> register are shifted right, copying the low-order bits into the high-order bit positions as they are shifted. The amount of shift is <const> in the “immediate” form or the value in <Rm> in the “register” form. If <Rd> is absent, the result is stored in <Rn>. If <Rd> is present, the result is stored there and <Rn> remains unchanged.

RRX

Rotate Right with eXtend.

RRX{S}{<c>}   {<Rd>,} <Rn>, <Rm>           % register
• If ‘S’ is present the condition flags are updated according to the result. If absent, the condition flags are not changed.

• <c> is the condition code, Table 9.2.1.

• <Rd> specifies the destination register, <Rn> is the source register, and <Rm> is the shift register.

All 32 bits in the Rn register are shifted right one bit position, copying the Carry Flag into the high-order bit position. If S is present, the low-order bit is copied into the Carry Flag. If Rd is absent, the result is stored in Rn. If Rd is present, the result is stored there and Rn remains unchanged.

In the solution to Exercise 4.4.1.1 we used an algorithm for converting a hexadecimal text string to an integer. The algorithm shifts the integer subtotal four bits to the left, converts the next hexadecimal character to the corresponding integer, and adds it to the subtotal. In this section we separate the algorithm into its own function, as shown in Listing 14.2.1. We use the writeLn function from Exercise 13.2.1.2 and the readLn function from Exercise 13.2.1.4. You will learn how to convert an integer to its corresponding decimal text string in Section 14.3 so we will use printf in this program.

The compiler-generated assembly language for the conversion algorithm is shown in Listing 14.2.2.

The algorithm used by the function in Listing 14.2.1 is straightforward, but it uses local variables on the stack and does not take advantage of the conditional execution feature of the ARM architecture. My assembly language solution in Listing 14.2.3 uses registers for local variables and the conditional execution option to implement a simple if-else construct.

The cmp instruction in the sequence:

cmp     r6, '9          @ alpha char?
subhi   r6, r6, gap     @ yes, remove gap
and     r6, r6, no_ascii  @ strip off acsii

compares the current character with the ASCII ‘9’. The sub instruction includes the hi option, so it is only executed if the character is higher in the ASCII sequence than a ‘9’. Thus the gap in the ASCII code between ‘9’ and ‘a’ is only subtracted if the character is a hexadecimal alpha character.

Conversion of an integer to the hex text string that represents it is a little more complex. We need to allocate memory space for the text string. The program in Listing 14.2.4 asks the user to enter a hexadecimal number, adds $1$ to the number, and displays the result in hexadecimal. This problem could, of course, be solved using only hexadecimal characters, but the addition is made much simpler by converting to the binary integer format, and then converting the result to hexadecimal characters.

The text string must be ordered from left to right, so we start with the high-order four bits. The ror instruction here:

ror     r5, r5, 28      @ no, get next 4 bits
and     r0, r5, 0xf     @ isolate the four bits

moves the high-order four bits into the lowest four-bit position in the register, while keeping the 32-bit pattern the same. We isolate the four bits with the and instruction and place the result in r0, where we can “build” the ASCII character. Some instruction set architectures have a rotate left instruction (e.g., rol on the Intel x86) but it really is not needed because rotation is a circular operation.

# Subsection14.2.1Exercises

##### 1

Show that the main function in Listing 14.2.1 works with the assembly language hexToInt function in Listing 14.2.3

Solution
##### 2

Does the program in in Exercise 14.2.1.2 work correctly for both lowercase and uppercase alphabetic hex characters? Why or why not?