Arithmetic and Logical
instructions

 

ADC : Addition with Carry

  ADC<suffix>  <dest>, <op 1>, <op 2>

                dest = op_1 + op_2 + carry
ADC will add the two operands, placing the result in the destination register. It uses a carry bit, so can add numbers larger than 32 bits. The following example will add two 128 bit numbers.
128 bit result: Registers 0, 1, 2, and 3
128 bit first: Registers 4, 5, 6, and 7
128 bit second: Registers 8, 9, 10, and 11.
  ADDS    R0, R4, R8              ; Add low words
  ADCS    R1, R5, R9              ; Add next word, with carry
  ADCS    R2, R6, R10             ; Add third word, with carry
  ADCS    R3, R7, R11             ; Add high word, with carry
If doing addition such as this, don't forget to set the S suffix so that the status of the Carry flag is updated.

 

 

ADD : Addition

  ADD<suffix>  <dest>, <op 1>, <op 2>

                dest = op_1 + op_2
ADD will add the two operands, placing the result in the destination register. Operand 1 is a register, operand 2 can be a register, shifted register, or an immediate value:
  ADD     R0, R1, R2              ; R0 = R1 + R2
  ADD     R0, R1, #256            ; R0 = R1 + 256
  ADD     R0, R2, R3,LSL#1        ; R0 = R2 + (R3 << 1)
The addition may be performed on signed or unsigned numbers.

 

 

AND : Logical AND

  AND<suffix>  <dest>, <op 1>, <op 2>

                dest = op_1 AND op_2
AND will perform a logical AND between the two operands, placing the result in the destination register; this is useful for masking the bits you wish to work on. Operand 1 is a register, operand 2 can be a register, shifted register, or an immediate value:
  AND     R0, R0, #3              ; R0 = Keep bits zero and one of R0,
                                         discard the rest.
An AND table (result = both):
  Op_1   Op_2   Result

  0      0      0
  0      1      0
  1      0      0
  1      1      1

 

 

BIC : Bit Clear

  BIC<suffix>  <dest>, <op 1>, <op 2>

                dest = op_1 AND (!op_2)
BIC is a way to clear bits within a word, a sort of reverse OR.
Operand two is a 32 bit bit mask. If a bit is set in the mask, it will be cleared. Unset mask bits indicate bits to be left alone.
  BIC     R0, R0, #%1011          ; Clear bits zero, one, and
                                    three in R0. Leave the
                                    remaining bits alone.
A BIC table:
  Op_1   Op_2   Result

  0      0      0
  0      1      0
  1      0      1
  1      1      0

 

 

EOR : Logical Exclusive OR

  EOR<suffix>  <dest>, <op 1>, <op 2>

                dest = op_1 EOR op_2
EOR will perform a logical Exclusive OR between the two operands, placing the result in the destination register; this is useful for inverting certain bits. Operand 1 is a register, operand 2 can be a register, shifted register, or an immediate value:
  EOR     R0, R0, #3              ; Invert bits zero and one in R0
An EOR table (result = either, but not both):
  Op_1   Op_2   Result

  0      0      0
  0      1      1
  1      0      1
  1      1      0

 

 

MOV : Move

  MOV<suffix>  <dest>, <op 1>

                dest = op_1
MOV loads a value into the destination register, from another register, a shifted register, or an immediate value.
You can specify the same register for the effect of a NOP instruction, or you can shift the same register if you choose:
  MOV     R0, R0                  ; R0 = R0... NOP instruction

  MOV     R0, R0, LSL#3           ; R0 = R0 * 8
If R15 is the destination, the program counter or flags can be modified. This is used to return to calling code, by moving the contents of the link register into R15:
  MOV     PC, R14                 ; Exit to caller

  MOVS    PC, R14                 ; Exit to caller preserving flags
                                    (not 32-bit compliant)

 

 

MVN : Move Negative

  MVN<suffix>  <dest>, <op 1>

                dest = !op_1
MVN loads a value into the destination register, from another register, a shifted register, or an immediate value.
The difference is the bits are inverted prior to moving, thus you can move a negative value into a register.
Due to the way this works (two's complement), you want to move one less than the required number:
  MVN     R0, #4                  ; R0 = -5

  MVN     R0, #0                  ; R0 = -1

 

 

ORR : Logical OR

  ORR<suffix>  <dest>, <op 1>, <op 2>

                dest = op_1 OR op_2
OR will perform a logical OR between the two operands, placing the result in the destination register; this is useful for setting certain bits to be set. Operand 1 is a register, operand 2 can be a register, shifted register, or an immediate value:
  ORR     R0, R0, #3              ; Set bits zero and one in R0
An OR table (result = either or both):
  Op_1   Op_2   Result

  0      0      0
  0      1      1
  1      0      1
  1      1      1

 

 

RSB : Reverse Subtraction

  RSB<suffix>  <dest>, <op 1>, <op 2>

                dest = op_2 - op_1
SUB will subtract operand one from operand two, placing the result in the destination register. Operand 1 is a register, operand 2 can be a register, shifted register, or an immediate value:
  RSB     R0, R1, R2              ; R0 = R2 - R1
  RSB     R0, R1, #256            ; R0 = 256 - R1
  RSB     R0, R2, R3,LSL#1        ; R0 = (R3 << 1) - R2
The subtraction may be performed on signed or unsigned numbers.

 

 

RSC : Reverse Subtraction with Carry

  RSC<suffix>  <dest>, <op 1>, <op 2>

                dest = op_2 - op_1 - !carry
This is the same as SBC, except the operands are subtracted the other way around.

 

 

SBC : Subtraction with Carry

  SBC<suffix>  <dest>, <op 1>, <op 2>

                dest = op_1 - op_2 - !carry
SBC will subtract the two operands, placing the result in the destination register. It uses the carry bit to represent 'borrow', so can subtract numbers larger than 32bits.
SUB and SBC generate the Carry flag the wrong way around, if a borrow is required then the carry flag is UNSET. Thus, this instruction requires a NOT Carry flag - it inverts the flag automatically during the instruction.

 

 

SUB : Subtraction

  SUB<suffix>  <dest>, <op 1>, <op 2>

                dest = op_1 - op_2
SUB will subtract operand two from operand one, placing the result in the destination register. Operand 1 is a register, operand 2 can be a register, shifted register, or an immediate value:
  SUB     R0, R1, R2              ; R0 = R1 - R2
  SUB     R0, R1, #256            ; R0 = R1 - 256
  SUB     R0, R2, R3,LSL#1        ; R0 = R2 - (R3 << 1)
The subtraction may be performed on signed or unsigned numbers.

 

 

SWP : Swap

  SWP<suffix>  <dest>, <op 1>, [<op 2>]
SWP will: If the destination and operand one are the same register, then the contents of the register and the contents of the memory location given will be swapped.
If the B suffix is set, then a byte will be transferred, otherwise a word will be transferred.


Return to assembler index
Copyright © 2004 Richard Murray