home | bit manipulation | data manipulation | addressing | loops | conditional execution/flags | about the author
useful documents | exercises | ARMulator | forum | links | c/c++ introduction | contact us | other websites by the author

Bit Processing

Bit manipulation instructions have simple operation, nevertheless it can be quite difficult to work out their effect on registers. A thorough understanding of the various number systems is essential here, it is also helpful to have an appreciation of the basic digital logic operations: AND(&), OR( | ), XOR, NOT(!).
Bit level operations have some very useful applications, as will be shown later a set of shift operations can be used to replace the MUL instruction for greater efficiency. As well as bit operations the ARM ISA provides a set of logical operations that can be performed on two registers, they follow:

BIC Rd, Rn, Rn2
AND Rd, Rn, Rn2
ORR Rd, Rn, Rn2
EOR Rd, Rn, Rn2


These instructions are often referred to as bit-wise logical operations. BIC and EOR are not so easy to decipher, they stand for 'BIT CLEAR' and 'EXCLUSIVE OR' respectively.


AND: Where there are 1s present in both Rn and Rn2 (i.e same bit both 1) the corresponding bit in Rd is set to 1, else it is set to 0. This is the Boolean AND operation. To illustrate this and example follows:

Rn:      00101010101010100100001111001111
Rn2:    01011110100101010101001010101010
Rd:      00001010100000000100001010001010



OR: Where there is at least one '1' present in either Rn or Rn2 (i.e either bit 1) the corresponding bit in Rd is set to 1, else it is set to 0. To illustrate this and example follows:

Rn:      00101010101010100100001111001111
Rn2:    01011110100101010101001010101010
Rd:      01111110101111111101001111101111



EOR: This is slightly more difficult; where either bit is 1 but NOT both then Rd is set to 1, else it is 0. This is the Boolean Exclusive OR operation and in digital electronics has the symbol ⊕. An example follows:

Rn:      00101010101010100100001111001111
Rn2:    01011110100101010101001010101010
Rd:      01110100101111110001000101100101



BIC: For every bit set to 1 in Rn2 the corresponding bit in Rn is set 0. And where there is a 0 in Rn2 the corresponding bit in Rn2 remains unchanged.

Rn:      00101010101010100100001111001111
Rn2:    01011110100101010101001010101010
Rd:      00100000001010100000000101000101

Register Logical Shifts

The ARM instruction set allows the user to manipulate the binary value in a register in another way. Register shifts can be used to 'rotate' (left or right), the the binary data stored in registers in several different ways. This makes use of the ALU's barrel shifter. Shifting is such a useful instruction as it allows for multiplication, an example follows:

Lets take a simple case: the decimal number 12 is stored in a register and we want to multiply it by 8.
This would appear as:
00000000000000000000000000001100 == 12
in the 32-bit register. But how do we multiply it by 8? Lets say we shifted it by 1 place to the left, we would get: 00000000000000000000000000011000 == 24 which is 2*12
Now lets do another test, now multiply by 2 places to the left. 00000000000000000000000000110000 == 48 which is 4*12
Here the pattern is multiply by n places to the left and we get a multiplication of 2^n in decimal. So we can say the following.

Shift by N places LEFT == multiply by 2^N

So to multiply by 8 we shift by 3, because 2^3 = 8. This is why shifts are so important. A table of the five barrel shifter operations follows:
ASR - arithmetic shift right
LSR - logical shift right
LSL - logical shift left
ROR - rotate right
RRX rotate right extended

The format of all shift instructions follows:
XXX R0, R1, SHIFT # XXX R0, R1, SHIFT Rn

Where SHIFT is a shift instruction. Notice here a register may be shifted by an immediate register (in the usual way by using a # followed by a number) or by a register.

LSL #n -logical shift left

MOV R0, R1, LSL #1

This would shift all bits in R1 by 1 place to the LEFT. Note you can only shift between 1 and 31 places. But what happens to the bits at the LSE (least significant end) ? i.e When all bits are shifted to the left the 'right most' bit now has to be set a new value. With LSL it is set to zero, example:
11010101010100101101111100001111
shifted by 1 place to the left we get: 10101010101001011011111000011110

ASL #n -Arithmetic shift left

MOV R0, R1, ASL #1

SAME AS LSL. This would shift all bits in R1 by 1 place to the LEFT. Note you can only shift between 1 and 31 places. But what happens to the bits at the LSE (least significant end) ? i.e When all bits are shifted to the left the 'right most' bit now has to be set a new value. With LSL and ASL it is set to zero, example:
11010101010100101101111100001111
shifted by 1 place to the left we get: 10101010101001011011111000011110

LSR #n -Logical shift right

MOV R0, R1, LSR #1

OPPOSITE of LSL! This would shift all bits in R1 by 1 place to the LEFT. Note you can only shift between 1 and 31 places. But now the 'left most' bits are filled with zeros.

ASR #n -Arithmetic shift right

MOV R0, R1, ASR #1

More complicated. This would shift all bits in R1 by 1 place to the LEFT. Note you can only shift between 1 and 31 places. But now the 'left most' bits are filled with zeros.

Click Here for a large range of ARM assembly books at low prices!

ARM Assembly Language - an Introduction by J. R. Gibson

ARM Assembly by William Hohl