In this Chapter, we will explore more of the ARM instructions set. Specifically, the instructions ADD,SUB,AND,ORR,EOR,BIC.
These instructions are quite similar in that they all have one of their operands shifted. Some examples:
add r0, r1, r2, LSR#2 - r0 = r1 + (r2 shifted right 2)
bic r9, r7, r3, ROR#16 - r9 = r7 &~ (r3 rotated right 16)
You don't have to shift, you very well could just do:
eor r3, r3, r3 - set r3 to zero (EOR is Exclusive OR).
The format for these instructions (and, actually, most ARM instructions) is:
INSTRUCTION DEST, OPERAND2, OPERAND3 [, SHIFTER OP #Number or Register]
The operation defined by INSTRUCTION will be preformed on OPERAND2 and the result of applying any shifter operation to OPERAND3. The result of the operation will be placed the register DEST. Only the DEST register is modified by any of this.
You may not be familiar with all of these, so here we go:
ADD/SUB - Your typical ADD and SUBtract. There is also a RSB instruction, which is a reversed subtract:
sub r0, r1, r2 - r0 = r1 - r2.
rsb r0, r1, r2 - r0 = r2 - r1.
AND - Does a bitwise AND operation. If you don't know your boolean logic, look here.
BIC - This is a neat instruction. It's similar to AND, except the bits that are set in the second operand clear bits in the first. In C, you'd do
this with &~ (an AND followed by a bit inversion). In fact, BIC stands for BIt Clear.
ORR - Does a bitwise OR operation.
Something to remember is that if you add an S to the instruction (ANDS, SUBS, ADDS, etc..), the status flags will be set. If you forget to use an S in a loop (like the one in the first program in Chapter 1) and you try to do a conditional branch, you'll get an infinite loop or other bad bugs.
You've seen this instruction before, but I need to explain it better. This instruction takes 2 operands and compares them.
It then sets the status flags on the result so that you can then do something conditional. It looks like this:
cmp r1, r0 - compare r1 to r0. This is the only way to end up with status'es such as Less Than (LT) and
Greater Than or Equal (GE). This is an important instruction. Note that you can use the shifter on this instruction too.
cmp r0, #160 - We've seen ones like that before. But what about:
cmp r1, r0, LSL#2 -
compares r1 to (r0 shifted up 2). Remember that CMP NEVER modifies the registers, since there's no destination register.
I bet you're wondering where that came from... Me too, this could have been a chapter by itself (a short one though). This
is something I could have mentioned before, but I waited. The fact is that with ARM instructions, they ALL can be
conditional. So that means:
orrlt r1, r3, r9 - If the status flags represent Less Than (LT), r1 = r3 OR r9. If the status flags don't represent the
condition supplied with the instruction, the instruction is skipped. This applies to ALL ARM instructions, there are no exceptions. Useful, eh?