Recap: Assembly View of the Machine CPU Memory Addresses Registers Code Data PC Data Condi7on Stack Instruc.ons Codes Sean Barker 1 Condition Codes OF Condi&on codes CF ZF SF CF: Carry flag (set if carry-out bit = 1) ZF: Zero flag (set if result = 0) SF: Sign flag (set if result top bit = 1) OF: Overflow flag (set if signed overflow) Sean Barker 2
Reading Condition Codes (also setz ) Sean Barker 3 Example: Greater Than Register Use(s) int gt (long x, long y) Argument x %rdi { return x > y; Argument y %rsi } Return value %rax cmpq %rsi, %rdi # Compare x:y setg %al # Set when > movzbl %al, %eax # Zero rest of %rax ret Sean Barker 4
Goto in C #include <stdio.h> int main() { int a = 0; FOO: while (a < 20) { if (a == 15) { a++; goto FOO; } printf("%d\n", a); a++; } return 0; } Sean Barker 5 Jumping Sean Barker 6
Example: absdiff absdiff: long absdiff cmpq %rsi, %rdi # x:y (long x, long y) jle .L4 { movq %rdi, %rax long result; subq %rsi, %rax if (x > y) ret result = x-y; .L4: # x <= y else movq %rsi, %rax result = y-x; subq %rdi, %rax return result; ret } Register Use(s) Argument x %rdi Argument y %rsi Return value %rax Sean Barker 7 absdiff with Goto long absdiff_j absdiff: (long x, long y) { cmpq %rsi, %rdi # x:y long result; jle .L4 int ntest = x <= y; movq %rdi, %rax if (ntest) goto Else; subq %rsi, %rax result = x-y; ret goto Done; .L4: # x <= y Else: movq %rsi, %rax result = y-x; subq %rdi, %rax Done: ret return result; } Sean Barker 8
Conditional to Goto t = test-expr if (!t) goto false; if (test-expr) then-cmd then-cmd goto done; else false: else-cmd else-cmd ... done: ... absdiff: cmpq %rsi, %rdi # x:y jle .L4 movq %rdi, %rax subq %rsi, %rax ret .L4: # x <= y movq %rsi, %rax subq %rdi, %rax ret Sean Barker 9 Bitbombs! 10101001 Sean Barker 10
Input in C with scanf int things_read; // numbers of things read by scanf int i; // declared but uninitialized char c; // read an int from user, store it at address &i things_read = scanf(“%d”, &i); // read an int and a char, store at addresses &i and &c things_read = scanf(“%d %c”, &i, &c); int i; // declared but uninitialized ... scanf(“%d”, i); // DANGER!!! Sean Barker 11 Do-While Loops C Code C Code Goto Version Goto Version long pcount_do long pcount_do long pcount_goto long pcount_goto (unsigned long x) { (unsigned long x) { (unsigned long x) { (unsigned long x) { long result = 0; long result = 0; long result = 0; long result = 0; do { do { loop: loop: result += x & 0x1; result += x & 0x1; result += x & 0x1; result += x & 0x1; x >>= 1; x >>= 1; x >>= 1; x >>= 1; } while (x); } while (x); if(x) goto loop; if(x) goto loop; return result; return result; return result; return result; } } } } Sean Barker 12
Do-While Loop Compilation Goto Version long pcount_goto (unsigned long x) { Register Use(s) long result = 0; Argument x %rdi loop: result += x & 0x1; %rax result x >>= 1; if(x) goto loop; return result; } movl $0, %eax # result = 0 .L2: # loop: movq %rdi, %rdx andl $1, %edx # t = x & 0x1 addq %rdx, %rax # result += t shrq %rdi # x >>= 1 jne .L2 # if (x) goto loop rep; ret Sean Barker 13 While Loops: Jump-to-Middle Goto Version goto test; loop: While version Body while ( Test ) test: Body if ( Test ) goto loop; done: Sean Barker 14
Jump-to-Middle Example C Code Jump to Middle Version long pcount_while long pcount_goto_jtm (unsigned long x) { (unsigned long x) { long result = 0; long result = 0; while (x) { goto test; result += x & 0x1; loop: x >>= 1; result += x & 0x1; } x >>= 1; return result; test: } if(x) goto loop; return result; } Sean Barker 15 While Loops: Guarded Do While version while ( Test ) Body Goto Version Do-While Version if (! Test ) if (! Test ) goto done; goto done; loop: do Body Body if ( Test ) while( Test ); goto loop; done: done: Sean Barker 16
Guarded Do Example C Code Do-While Version long pcount_while long pcount_goto_dw (unsigned long x) { (unsigned long x) { long result = 0; long result = 0; while (x) { if (!x) goto done; result += x & 0x1; loop: x >>= 1; result += x & 0x1; } x >>= 1; return result; if(x) goto loop; } done: return result; } Sean Barker 17 Guarded Do Optimization int x = 0; if (x >= 5) goto done; int x = 0; loop: while (x < 5) { print(x); print(x); x++; x++; if (x >= 5) goto loop; } done: ... Sean Barker 18
For Loops for ( init ; test ; update ) { body } init while ( test ) { body update } Sean Barker 19 Switch Statements void print_grade_range(char letter_grade) { switch (letter_grade) { case ‘A’: printf(“90-100\n”); break; case ‘B’: printf(“80-89\n”); break; case ‘C’: printf(“70-79\n”); break; case ‘D’: printf(“60-79\n”); break; case ‘F’: printf(“0-59\n”); break; default: printf(“Invalid grade\n”); break; } } Sean Barker 20
Switch Fall Through long switch_eg (long x, long y, long z) { long w = 1; switch(x) { case 1: w = y*z; break; case 2: w = y/z; /* Fall Through */ case 3: w += z; break; case 5: case 6: w -= z; break; default: w = 2; } return w; } Sean Barker 21 Jump Tables Jump Table Switch Form switch(x) { Targ0: Code Block jtab: Targ0 case val_0: 0 Block 0 Targ1 case val_1: Targ2 Targ1: Code Block Block 1 • • • • 1 • case val_n-1: • Block n–1 Targ2: Code Block Targn-1 } 2 • Transla:on (Extended C) • goto *jtab[x]; • Targn-1: Code Block n–1 Sean Barker 22
Switch Example Jump table long switch_eg .section .rodata (long x, long y, long z) .align 8 { .L4: long w = 1; .quad .L8 # x = 0 switch(x) { .quad .L3 # x = 1 case 1: .quad .L5 # x = 2 w = y*z; .quad .L9 # x = 3 break; .quad .L8 # x = 4 case 2: .quad .L7 # x = 5 w = y/z; .quad .L7 # x = 6 /* Fall Through */ case 3: w += z; break; case 5: case 6: switch_eg: w -= z; movq %rdx, %rcx break; cmpq $6, %rdi # x:6 default: ja .L8 # Use default w = 2; jmp *.L4(,%rdi,8) # goto *JTab[x] } return w; } Sean Barker 23 Example Jump Table Jump table switch(x) { case 1: // .L3 .section .rodata w = y*z; .align 8 break; .L4: .quad .L8 # x = 0 case 2: // .L5 .quad .L3 # x = 1 w = y/z; .quad .L5 # x = 2 /* Fall Through */ .quad .L9 # x = 3 .quad .L8 # x = 4 case 3: // .L9 .quad .L7 # x = 5 w += z; .quad .L7 # x = 6 break; case 5: case 6: // .L7 w -= z; break; default: // .L8 w = 2; } Sean Barker 24
Code Blocks switch_eg: long w = 1; movq %rdx, %rcx switch(x) { cmpq $6, %rdi # x:6 case 1: // .L3 ja .L8 # Use default w = y*z; jmp *.L4(,%rdi,8) # goto *JTab[x] break; case 2: // .L5 .L3: # Case 1 w = y/z; movq %rsi, %rax # y /* Fall Through */ imulq %rdx, %rax # y*z case 3: // .L9 ret w += z; .L5: # Case 2 break; movq %rsi, %rax case 5: cqto case 6: // .L7 idivq %rcx # y/z w -= z; jmp .L6 # goto merge break; .L9: # Case 3 default: // .L8 movl $1, %eax # w = 1 w = 2; .L6: # merge: } addq %rcx, %rax # w += z return w; ret .L7: # Case 5,6 movl $1, %eax # w = 1 subq %rdx, %rax # w -= z ret .L8: # Default: movl $2, %eax # 2 ret Sean Barker 25 Procedure Call Registers %rax %r8 %eax %r8d Return Arg 5 %rbx %r9 %ebx %r9d Arg 6 %rcx %r10 %ecx %r10d Arg 4 %rdx %r11 %edx %r11d Arg 3 %rsi %r12 %esi %r12d Arg 2 %rdi %r13 %edi %r13d Arg 1 %rsp %r14 %esp %r14d Stack ptr %rbp %r15 %ebp %r15d Sean Barker 26
Recommend
More recommend