Machine-Level Programming
Machine-Level Programming
Condition Codes
Single Bit Registers
CF Carry Flag SF Sign Flag
ZF Zero Flag OF Overflow Flag
Implicitly Set By Arithmetic Operations
addl Src,Dest
C analog: t = a + b
– CF set if carry out from most significant bit
• Used to detect unsigned overflow
• CF = C
– ZF set if t == 0
– SF set if t < 0
– OF set if two’s complement overflow
(a>0 && b>0 && t<0) || (a<0 && b<0 && t>=0)
Not Set by leal instruction
2
[註|例] 상태표시 코드
명령이 플래그에 미치는 영향 명령 ZF SF CF OF
and √ √ 0 0
명령 ZF SF CF OF or √ √ 0 0
add √ √ √ √ xor √ √ 0 0
adc √ √ √ √ not
sub √ √ √ √ test √ √ 0 0
sbb √ √ √ √ bt √
neg √ √ √ √ btc/btr/bts √
dec √ √ √ rcl √ √
cmp √ √ √ √ rol √ √
mul ? ? √ √ shr √ √ √ √
imul ? ? √ √ sar √ √ √ √
div ? ? ? ? rcr √ √
idv ? ? ? ? ror √ √
5
Zero Flag and Sign Flag (in 8-bit operation)
3) ZF – set if answer is $00
4) SF – MSB of result; sign bit (valid only for signed numbers)
7
Setting Condition Codes (cont.)
Explicit Setting by Test instruction
testl Src2,Src1
– Sets condition codes based on value of Src1 & Src2
• Useful to have one of the operands be a mask
– testl b,a like computing a&b without setting destination
– ZF set when a&b == 0
– SF set when a&b < 0
8
Reading Condition Codes
SetX Instructions (setX D: D ConditionCodes)
– Set single byte based on combinations of condition codes
%esi
int gt (int x, int y)
{ %edi
return x > y;
%esp
}
Body %ebp
movl 12(%ebp),%eax # eax = y
cmpl %eax,8(%ebp) # Compare x : y Note
setg %al # al = x > y inverted
movzbl %al,%eax # Zero rest of %eax ordering!
10
Jumping
jX Instructions (jX Label or jX *Operand)
– Jump to different part of code depending on condition codes
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)
11
Direct and Indirect Jump
Direct jump (give the Indirect jump examples
jump target directly in (should refer the value
the operand) of register or memory to
get the jump target)
xorl %eax, %eax jmp *%eax
jmp .L1
movl (%eax), %edx
.L1: jmp *(%eax)
popl %edx
Conditional jumps
can only be direct
12
Conditional Branch Example
_max:
pushl %ebp
Set
movl %esp,%ebp
Up
int max(int x, int y)
{ movl 8(%ebp),%edx
if (x > y) movl 12(%ebp),%eax
return x; cmpl %eax,%edx Body
else jle L9
return y; movl %edx,%eax
} L9:
movl %ebp,%esp
popl %ebp Finish
ret
13
“Do-While” Loop Example
14
“Do-While” Loop Compilation
15
General “Do-While” Translation
C Code Goto Version
do loop:
Body Body
while (Test); if (Test)
goto loop
17
Actual “While” Loop Translation
18
General “While” Translation
C Code
while (Test)
Body
19
“For” Loop Example
/* Compute x raised to nonnegative power p */
int ipwr_for(int x, unsigned p) {
int result;
for (result = 1; p != 0; p = p>>1) {
if (p & 0x1)
result *= x;
x = x*x;
}
return result;
}
Algorithm
– Exploit property that p = p0 + 2p1 + 4p2 + … 2n–1pn–1
– Gives: xp = z0 ·z1 2 ·(z2 2) 2 ·… ·(…((zn –12) 2 )…) 2
zi = 1 when pi = 0
zi = x when pi = 1 Example
n–1 times
– Complexity O(log p) 310 = 32 * 38
= 32 * ((32) 2) 2
20
ipwr Computation
/* Compute x raised to nonnegative power p */
int ipwr_for(int x, unsigned p) {
int result;
for (result = 1; p != 0; p = p>>1) {
if (p & 0x1)
result *= x;
x = x*x;
}
return result;
}
result x p
1 3 10
1 9 5
9 81 2
9 6561 1
531441 43046721 0
21
“For” Loop Example
General Form
int result;
for (result = 1; for (Init; Test; Update )
p != 0;
p = p>>1) { Body
if (p & 0x1)
result *= x;
x = x*x;
}
{
Body if (p & 0x1)
result *= x;
x = x*x;
}
22
“For” “While”
For Version While Version
for (Init; Test; Update ) Init;
while (Test ) {
Body
Body
Update ;
}
Do-While Version
Init; Goto Version
if (!Test)
goto done; Init;
do { if (!Test)
Body goto done;
Update ; loop:
} while (Test) Body
done: Update ;
if (Test)
goto loop;
done:
23
“For” Loop Compilation
25
Jump Table Structure
Switch Form Jump Table Jump Targets
switch(op) { jtab: Targ0 Targ0:
Code Block
case val_0: 0
Targ1
Block 0
case val_1: Targ2
Targ1:
Block 1 • Code Block
• • • • 1
case val_n-1: •
Block n–1 Targ2:
Targn-1 Code Block
} 2
•
Approx. Translation •
target = JTab[op]; •
goto *target;
Targn-1:
Code Block
n–1
26
Switch Statement Example
Branching Possibilities Enumerated Values
typedef enum ADD 0
{ADD, MULT, MINUS, DIV, MOD, BAD} MULT 1
op_type; MINUS 2
DIV 3
char unparse_symbol(op_type op) MOD 4
{ BAD 5
switch (op) {
• • •
}
}
unparse_symbol:
pushl %ebp # Setup
movl %esp,%ebp # Setup
movl 8(%ebp),%eax # eax = op
Setup: cmpl $5,%eax # Compare op : 5
ja .L49 # If > goto done
jmp *.L57(,%eax,4) # goto Table[op]
27
Jump Table
Table Contents Targets & Completion
.section .rodata .L51:
.align 4 movl $43,%eax # ’+’
.L57: jmp .L49
.long .L51 #Op = 0 .L52:
.long .L52 #Op = 1 movl $42,%eax # ’*’
.long .L53 #Op = 2 jmp .L49
.long .L54 #Op = 3 .L53:
.long .L55 #Op = 4 movl $45,%eax # ’-’
.long .L56 #Op = 5 jmp .L49
.L54:
Enumerated Values movl $47,%eax # ’/’
ADD 0 jmp .L49
MULT 1 .L55:
MINUS 2 movl $37,%eax # ’%’
DIV 3 jmp .L49
MOD 4 .L56:
BAD 5 movl $63,%eax # ’?’
# Fall Through to .L49
28
Assembly Setup Explanation
Symbolic Labels
– Labels of form .LXX translated into addresses by assembler
Table Structure
– Each target requires 4 bytes
– Base address at .L57
Jumping
jmp .L49
– Jump target is denoted by label .L49
jmp *.L57(,%eax,4)
– Start of jump table denoted by label .L57
– Register %eax holds op
– Must scale by factor of 4 to get offset into table
– Fetch target from effective Address .L57 + op*4
29
Switch Statement Completion
.L49: # Done:
movl %ebp,%esp # Finish
popl %ebp # Finish
ret # Finish
Puzzle
– What value returned when op is invalid?
Answer
– Register %eax set to op at beginning of procedure
– This becomes the returned value
30
Object Code
Setup
– Label .L49 becomes address 0x804875c
– Label .L57 becomes address 0x8048bc0
08048718 <unparse_symbol>:
8048718: 55 pushl %ebp
8048719: 89 e5 movl %esp,%ebp
804871b: 8b 45 08 movl 0x8(%ebp),%eax
804871e: 83 f8 05 cmpl $0x5,%eax
8048721: 77 39 ja 804875c <unparse_symbol+0x44>
8048723: ff 24 85 c0 8b jmp *0x8048bc0(,%eax,4)
31
Object Code (cont.)
Jump Table
– Doesn’t show up in disassembled code
– Can inspect using GDB
gdb code-examples
(gdb) x/6xw 0x8048bc0
• Examine 6 hexadecimal format “words” (4-bytes each)
• Use command “help x” to get format documentation
0x8048bc0 <_fini+32>:
0x08048730
0x08048737
0x08048740
0x08048747
0x08048750
0x08048757
32
Extracting Jump Table from Binary
Jump Table Stored in Read Only Data Segment (.rodat
a)
– Various fixed values needed by your code
Can examine with objdump
objdump code-examples –s –-section=.rodata
– Show everything in indicated segment.
Hard to read
– Jump table entries shown with reversed byte ordering
Contents of section .rodata:
8048bc0 30870408 37870408 40870408 47870408 [email protected]...
8048bd0 50870408 57870408 46616374 28256429 P...W...Fact(%d)
8048be0 203d2025 6c640a00 43686172 203d2025 = %ld..Char = %
…
33
Disassembled Targets
34
Matching Disassembled Targets
8048730: b8 2b 00 00 00 movl
8048735: eb 25 jmp
Entry 8048737: b8 2a 00 00 00 movl
0x08048730 804873c: eb 1e jmp
804873e: 89 f6 movl
0x08048737 8048740: b8 2d 00 00 00 movl
0x08048740 8048745: eb 15 jmp
0x08048747 8048747: b8 2f 00 00 00 movl
0x08048750 804874c: eb 0e jmp
804874e: 89 f6 movl
0x08048757
8048750: b8 25 00 00 00 movl
8048755: eb 05 jmp
8048757: b8 3f 00 00 00 movl
35
Summarizing
C Control
– if-then-else
– do-while
– while
– switch
Assembler Control
– jump
– Conditional jump
Compiler
– Must generate assembly code to implement more complex control
Standard Techniques
– All loops converted to do-while form
– Large switch statements use jump tables
36