Joseph Haugh
University of New Mexico
CF
, carry flag (unsigned) | SF
, sign flag (signed)ZF
, zero flag | OF
, overflow flag (signed)CF
set if carry out from most significant bit (unsigned overflow)ZF
set if t == 0
SF
set if t < 0
(as signed)OF
set if two’s-complement (signed) overflow
(a>0 && b>0 && t<0) || (a<0 && b<0 && t>=0)
cmp_
test_
cmpq b,a
like computing a-b
without setting destinationCF
set if carry out from most significant bit (used for unsigned comparisons)ZF
set if a == bSF
set if (a-b) < 0 (as signed)OF
set if two’s-complement (signed) overflow
(a>0 && b<0 && (a-b)<0) || (a<0 && b>0 && (a-b)>0)
testq b,a
like computing a&b
without setting destinationb&a
ZF
set when a&b == 0
SF
set when a&b < 0
SetX | Condition | Description |
---|---|---|
sete | ZF | Equal / Zero |
setne | ~ZF | Not Equal / Not Zero |
sets | SF | Negative |
setns | ~SF | Nonnegative |
setg | ~(SF^OF)&~ZF |
Greater (Signed) |
setge | ~(SF^OF) | Greater or Equal (Signed) |
setl | (SF^OF) | Less (Signed) |
setle | (SF^OF)|ZF |
Less or Equal (Signed) |
seta | ~CF&~ZF |
Above (Unsigned) |
setb | CF | Below (Unsigned) |
movzbl
to finish job
Register | Use |
---|---|
%rdi | Argument x |
%rsi | Argument y |
%rax | Return value |
int gt (long x, long y)
{
return x > y;
}
cmpq %rsi, %rdi # Compare (x-y)
setg %al # Set when >
movzbl %al, %eax # Zero rest of %rax
ret
int comp(data_t a, data_t b) {
return a COMP b;
}
Suppose a
is in some portion of %rdi
and b
in %rsi
, which data type data_t
and which comparison COMP
could cause the compiler to generate this code?
cmpl %esi, %edi
setl %al
int comp(data_t a, data_t b) {
return a COMP b;
}
Suppose a
is in some portion of %rdi
and b
in %rsi
, which data type data_t
and which comparison COMP
could cause the compiler to generate this code?
cmpl %esi, %edi # a - b
setl %al # if a < b,
# set first byte of %rax
data_t
is Int
COMP
is <
int comp(data_t a, data_t b) {
return a COMP b;
}
Suppose a
is in some portion of %rdi
and b
in %rsi
, which data type data_t
and which comparison COMP
could cause the compiler to generate this code?
cmpw %si, %di
setge %al
int comp(data_t a, data_t b) {
return a COMP b;
}
Suppose a
is in some portion of %rdi
and b
in %rsi
, which data type data_t
and which comparison COMP
could cause the compiler to generate this code?
cmpw %si, %di # a -b
setge %al # if a >= b,
# set first byte of %rax
data_t
is Short
COMP
is >=
jX | Condition | Description |
---|---|---|
jmp | 1 | Unconditional |
je | ZF | Equal / Zero |
jne | ~ZF | Not Equal / Not Zero |
js | SF | Negative |
jns | ~SF | Nonnegative |
jg | ~(SF^OF)&~ZF |
Greater (Signed) |
jge | ~(SF^OF) | Greater or Equal (Signed) |
jl | (SF^OF) | Less (Signed) |
jle | (SF^OF)|ZF |
Less or Equal (Signed) |
ja | ~CF&~ZF |
Above (Unsigned) |
jb | CF | Below (Unsigned) |
A direct jump is a jump to a label in your code
movq $0,%rax # Set %rax to 0
jmp .L1 # Goto .L1
movq (%rax), %rdx # Null pointer dereference (skipped)
.L1:
popq %rdx # Jump target
An indirect jump is a jump
*
before the argumentjmp *%rax # jump to the value in %rax
jmp *(%rax) # jump to the value in memory at the address in %rax
jmp target + next address
1 movq %rdi, %rax
2 jmp .L2
3 .L3:
4 sarq %rax
5 .L2:
6 testq %rax, %rax
7 jg .L3
8 rep; ret
1 0: 48 89 f8 mov %rdi,%rax
2 3: eb 03 jmp 8 <loop+0x8>
3 5: 48 d1 f8 sar %rax
4 8: 48 85 c0 test %rax,%rax
5 b: 7f f8 jg 5 <loop+0x5>
6 d: f3 c3 repz retq
0x03 + 0x05 = 0x08
0xf8 + 0x0d = 0x05
je
instruction below?4003fa: 74 02 je XXXXXX
4003fc: ff d0 callq *%rax
je
instruction below?
4003fc + 2 = 4003fe
4003fa: 74 02 je 4003fe
4003fc: ff d0 callq *%rax
je
instruction below?40042f: 74 f4 je XXXXXX
400431: 5d pop %rbp
je
instruction below?
400431 + f4 = 400425
0xf4 = -12
400431 - C
4003fa: 74 02 je 400425
4003fc: ff d0 callq *%rax
je
and pop
instruction below?XXXXXX: 77 02 je 400547
YYYYYY: 5d pop %rbp
je
instruction below?
YYYYYY + 2 = 400547
thus, YYYYYY = 400545
XXXXXX = 400545 - 2 = 4000543
(why - 2?)XXXXXX: 77 02 je 400547
YYYYYY: 5d pop %rbp
Generating:
b146> gcc –Og -S –fno-if-conversion control.c
long absdiff (long x, long y)
{
long result;
if (x > y)
result = x-y;
else
result = y-x;
return result;
}
absdiff:
cmpq %rsi, %rdi # x - y
jle .L2
movq %rdi, %rax
subq %rsi, %rax
ret
.L2: # x <= y
movq %rsi, %rax
subq %rdi, %rax
ret
goto
statementlong absdiff (long x, long y)
{
long result;
if (x > y)
result = x-y;
else
result = y-x;
return result;
}
long absdiff_j (long x, long y)
{
long result;
int ntest = x <= y;
if (ntest) goto Else;
result = x-y;
goto Done;
Else:
result = y-x;
Done:
return result;
}
if
statement of the form:if (test-expr) {
then-stmts
}
else {
else-stmts
}
t = test-expr;
if (!t)
goto False;
then-stmts
goto Done;
False:
else-stmts
Done:
...
val = test-expr ? then-expr : else-expr;
t = !test-expr
if (t)
goto Else;
val = then-expr;
goto Done;
Else:
val = else-expr;
Done:
...
val = test-expr ? then-expr : else-expr;
result = then-expr;
eval = else-expr;
nt = !test-expr
if (nt) result = eval;
return result;
long absdiff (long x, long y)
{
long result;
if (x > y)
result = x-y;
else
result = y-x;
return result;
}
Register | Use |
---|---|
%rdi | Argument x |
%rsi | Argument y |
%rax | Return Value |
absdiff:
movq %rdi, %rax # x
subq %rsi, %rax # result = x-y
movq %rsi, %rdx
subq %rdi, %rdx # eval = y-x
cmpq %rsi, %rdi # x:y
cmovle %rdx, %rax # if <=, result = eval
ret
Expensive Computations:
val = Test(x) ? Hard1(x) : Hard2(x);
Risky Computations
val = p ? *p : 0;
Computations With Side Effects
val = x > 0 ? x *= 7 : x += 3;