To compare data (and set the appropriate flags,) without modifying a register we have the following instructions:
TEST arg1, arg2
TEST
,
Test performs a bit-wise logical AND between arg1 and arg2 (discarding result) setting the following flags:
flags: Result: SF MostSignificantBit(result) ZF (result == 0) PF 1 iff result has even number of bits CF 0 OF 0 AF undefined
CMP arg1, arg2
CMP
Comparison (signed subtraction of arg2 from arg1), result is discarded.
Flags affected: SF,ZF,PF,CF,OF,AF
SF
ZF
PF
CF
OF
AF
OR reg, reg
OR
If both arguments are the same register, ORing the register with itself will not modify the value of the register, but will set the flags indicating that it is zero or not and the state of the sign bit (i.e. the upper most bit,) which can be used by the jump instructions. This faster than using CMP to test a register for zero or positive/negative.
Normally the instruction pointer points the next instruction and is simply incremented to the next instruction as instructions are loaded from memory. A jump is when the code branches to a new location in memory. This is accomplished by a jump instruction that loads a new address into the instruction pointer where the CPU will pull the next instruction from.
Jump statements come in two forms, un-conditional jumps, i.e. the jump is always taken and conditional, i.e. the jump is taken only if some condition (i.e. state of the flags) is met.
JMP location
JMP
Always jumps to location which may be an Immediate address, or an address stored in a Register or Memory.
Jcc location
J
Where cc above is replaced by a condition, such as E for equal, LE for less than or equal, etc. Conditional jumps always only take an immediate address and cannot use a register or memory as the location to jump to.
Below are a small selection of the more important conditional jumps. There are many more (even more than listed in the handout)
Jump if: Flags: JE loc Equal ZF == 1 JNE loc Not equal ZF == 0 JG loc Greater than SF == OF and ZF == 0 JGE loc Greater than or equal SF == OF or ZF == 1 JL loc Lesser than SF != OF JLE loc Lesser than or equal SF != OF or ZF == 1 JZ loc Jump if zero ZF == 1 JNZ loc Jump if not zero ZF == 0
JE
JNE
JG
JGE
JL
JLE
JZ
JNZ
What follows are common conversions from a higher level language to assembly.
Note that the labels used in the assembly should be customized to the code being written. Consider appending numbers to the labels to make them unique and if you need to nest them, i.e. .while0:, etc.
.while0:
The "instruction" jcc below represents one of the conditional jump instructions and should not be taken literally.
C code: Assembly Code: ───────────────────────────────────────────────────────────────────────── ┊ ┌────────────┐ ┊ ┌────────────┐ if ( │ expression │ ) { ──────────────────────▷ │ expression │ └────────────┘ ┊ └────────────┘ ┌────────────┐ ┊ jcc .else ───┐ │ statements ├───────────────────┐ │ └────────────┘ ┊ │ ┌ ┌────────────┐ ┐ │ ┊ └─────────▷│ │ statements │ │ │ } else { ┊ │ └────────────┘ │ │ ┊ └ jmp .done ┘ ─────┐ ┌─────────────────┐ ┊ │ │ │ else-statements ├───────────────┐ .else: ◁──┘ │ └─────────────────┘ ┊ │ ┌─────────────────┐ │ ┊ └─────────▷ │ else-statements │ │ } ┊ └─────────────────┘ │ ┊ │ ┊ .done: ◁────┘ ┌─────────────────┐ ┊ ┌─────────────────┐ │ More statements ├───────────────────────────▷ │ More statements │ └─────────────────┘ ┊ └─────────────────┘
In the case of an if statement with no matching else part, then:
.else:
else-statements
jmp .done
statements
.done
C code: Assembly Code: ───────────────────────────────────────────────────────────────────────── ┌─────────────────┐ ┊ ┌─────────────────┐ │ init expression ├───────────────────────────▷ │ init expression │ └─────────────────┘ ┊ └─────────────────┘ ┊ .while: ◁──┐ ┌─────────────────┐ ┊ ┌─────────────────┐ │ while( │ test expression │ ) { ──────────────▷ │ test conditions │ │ └─────────────────┘ ┊ └─────────────────┘ │ ┊ jcc .done ───│─┐ ┌────────────┐ ┊ │ │ │ statements ├────────────────┐ ┌────────────┐ │ │ └────────────┘ ┊└────────────▷ │ statements │ │ │ ┊ └────────────┘ │ │ } ┊ jmp .while ───┘ │ ┊ │ ┊ .done: ◁────┘ ┌─────────────────┐ ┊ ┌─────────────────┐ │ More statements ├───────────────────────────▷ │ More statements │ └─────────────────┘ ┊ └─────────────────┘
break
jmp
continue
.while
NOTE: The conditional branch to .done has the reverse sense to the while statements test expression, i.e. leave the loop if any of the test conditions are false, rather than continuing the loop so long as the test expression is true as in the C case.
C code: Assembly Code: ───────────────────────────────────────────────────────────────────────── ┊ ┌─────────────────┐ ┌─────────────────┐ ┊ ┌─────────▷ │ init expression │ for ( │ init expression │ ; ───────┘ └─────────────────┘ └─────────────────┘ ┊ .for: ┌─────────────────┐ ┊ ┌─────────────────┐ │ test expression │ ; ─────────────────▷ │ test conditions │ └─────────────────┘ ┊ └─────────────────┘ ┌─────────────────┐ ┊ jcc .done │ inc. expression │ ) { ──────┐ └─────────────────┘ ┊ │ ┌────────────┐ ┊ ┌──│────────▷ │ statements │ ┌────────────┐ ┊ │ │ └────────────┘ │ statements ├────────────────┘ │ .inc: └────────────┘ ┊ │ ┌─────────────────┐ ┊ └────────▷ │ inc. expression │ } ┊ └─────────────────┘ ┊ jmp .for ┌─────────────────┐ ┊ │ More statements ├──────────────┐ .done: └─────────────────┘ ┊ │ ┌─────────────────┐ ┊ └───────────▷ │ More statements │ ┊ └─────────────────┘
.inc
The C do-while loop loops at least once. It is also the most natural loop style to do in assembly if one knows they are going to loop at least once as it requires only a single conditional jump in order to repeat the loop.
C code: Assembly Code: ───────────────────────────────────────────────────────────────────────── ┊ do { ┊ .do: ◁──┐ ┊ │ ┌────────────┐ ┊ ┌────────────┐ │ │ statements ├─────────────────────────────▷ │ statements │ │ └────────────┘ ┊ └────────────┘ │ ┊ │ ┊ .continue: │ ┌─────────────────┐ ┊ ┌─────────────────┐ │ while( │ test expression │ ) { ──────────────▷ │ test conditions │ │ └─────────────────┘ ┊ └─────────────────┘ │ ┊ jcc .do ───┘ ┊ ┊ .break: ┌─────────────────┐ ┊ ┌─────────────────┐ │ More statements ├───────────────────────────▷ │ More statements │ └─────────────────┘ ┊ └─────────────────┘
NOTE: The break and continue labels are unnecessary if you have no break or continue statements that require them.
.break
.continue