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 == 0SF 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&aZF set when a&b == 0SF 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 IntCOMP 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 ShortCOMP 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 targetAn 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 %raxjmp target + next address1 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 = 0x080xf8 + 0x0d = 0x05je instruction below?4003fa: 74 02 je XXXXXX
4003fc: ff d0 callq *%rax
je instruction below?
4003fc + 2 = 4003fe4003fa: 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 = 4004250xf4 = -12400431 - C4003fa: 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 = 400545XXXXXX = 400545 - 2 = 4000543 (why - 2?)XXXXXX: 77 02 je 400547
YYYYYY: 5d pop %rbp
Generating:
b146> gcc –Og -S –fno-if-conversion control.clong 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;