Recall that every instruction has an optional label:
LABEL: OPERATOR OPERANDS ; COMMENT
The label is a symbolic name for the address of the instruction.
The unconditional jump (goto, branch) instruction:
jmp LABEL ; eip = LABEL
Recall that most instructions set certain flags in the eflags register as a side effect.
For example, the instruction:
add al, bl ; al = result = al + bl
sets the following flags:
if (result == 0) ZF = 1 else ZF = 0
if (result < 0) SF = 1 else SF = 0
if (carry out == 1) CF = 1 else CF = 0
if (sign of result wrong) OF = 1 else OF = 0
For example, assume:
al = 0x7f = 127
bl = 0x01 = 1
then:
al + bl = 0x80 = 128 = -128 (signed interpretation)
and:
ZF = 0
SF = 1
CF = 0
OF = 1
We can see from this that if we are doing unsigned addition, then we have the correct answer (because CF = 0), but if we are doing unsigned arithmetic, then our answer is incorrect (because OF = 1).
As another example, assume:
al = 0xFF = 255 = -1 (signed interpretation)
bl = 0x01 = 1
then:
al + bl = 0x00 = 0
and:
ZF = 1
SF = 0
CF = 1
OF = 0
We can see from this that if we are doing unsigned addition, then our answer is wrong (because CF = 1) but that if we are doing signed addition, then our answer is correct (because OF = 0).
A conditional jump involves two steps. First an instruction is executed that sets the status flags, then a conditional jump instruction jumps if certain combinations of the status flags are set or clear.
The Pentium has three groups of conditional jumps:
Jumps Based on a Single Flag |
||||
Operation |
Meaning |
Condition |
Opposite |
Notes |
jz, je |
jump if zero (equal) |
ZF = 1 |
jnz, jne |
signed or unsigned |
jc, jb, jnae |
jump if carry (below, not above equal) |
CF = 1 |
jnc, jnb, jae |
unsigned |
js |
jump if sign |
SF = 1 |
jns |
|
jo |
jump if overflow |
OF = 1 |
jno |
|
jpe, jp |
jump if parity even |
PF = 1 |
jpo |
|
|
||||
Jumps Based on Signed Comparisons |
||||
jg, jnle |
jump if x > y, x !<= y |
ZF = 0 && SF = OF |
jng, jle |
|
jl, jnge |
jump if x < y, x !>= y |
SF != OF |
jnl, jge |
|
|
||||
Jumps Based on Unsigned Comparisons |
||||
ja, jbne |
jump if x > y, x !<= y |
CF = 0 && ZF = 0 |
jna, jbe |
|
jbe, jna |
jump if x <= y, x !> y |
CF = 1 || ZF = 1 |
jbne, ja |
|
The compare instruction is useful as it sets the flags without affecting any other part of memory:
cmp A, B ; compute A – B, set flags
For example, assume:
al = 0x01 = 1
bl = 0xff = -1
Where does the following code send control?
cmp al, bl ; result = al –
bl = 2 ZF = 0,SF = 0,OF = 0,CF = 1
jg DONE1
; if (ZF = 0 && SF == OF) jump DONE1
ja DONE2 ; if (CF == 0 && ZF
== 0) jump DONE2
Assume:
int x, y;
Here is a typical 2-way conditional:
if (x < y) {
task1;
} else {
task2;
}
Here is how it might be translated into assembly:
cmp x, y
jge ELSE
task1
jmp DONE
ELSE:
task2
DONE:
Here is a typical while-loop:
while(x < y) {
task;
}
And a translation into assembly:
WHILE:
cmp x, y
jge DONE
task
jmp WHILE
DONE:
Recall the nth triangle number is the number of bricks needed to build a staircase of height n:
Clearly the answer is 1 + 2 + 3 + ... + n.
We can compute the nth triangle number using iteration.
Here is our solution: