1 / 42

Reading Condition Codes (Cont.)

Reading Condition Codes (Cont.). SetX Instructions Set single byte based on combinations of condition codes One of 8 addressable byte registers Embedded within first 4 integer registers Does not alter remaining 3 bytes Typically use movzbl to finish job. %eax. %ah. %al. %edx. %dh.

mrosenblum
Download Presentation

Reading Condition Codes (Cont.)

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Reading Condition Codes (Cont.) • SetX Instructions • Set single byte based on combinations of condition codes • One of 8 addressable byte registers • Embedded within first 4 integer registers • Does not alter remaining 3 bytes • Typically use movzbl to finish job %eax %ah %al %edx %dh %dl %ecx %ch %cl %ebx %bh %bl %esi int gt (int x, int y) { return x > y; } %edi %esp Body %ebp movl 12(%ebp),%eax # eax = y cmpl %eax,8(%ebp) # Compare x : y setg %al # al = x > y movzbl %al,%eax # Zero rest of %eax Note inverted ordering!

  2. Jumping • jX Instructions • Jump to different part of code depending on condition codes

  3. Conditional Branch Example _max: pushl %ebp movl %esp,%ebp movl 8(%ebp),%edx movl 12(%ebp),%eax cmpl %eax,%edx jle L9 movl %edx,%eax L9: leave ret Set Up int max(int x, int y) { if (x > y) return x; else return y; } Body Finish

  4. Conditional Branch Example (Cont.) int goto_max(int x, int y) { int rval = y; int ok = (x <= y); if (ok) goto done; rval = x; done: return rval; } • C allows “goto” as means of transferring control • Closer to machine-level programming style • Generally considered bad coding style movl 8(%ebp),%edx # edx = x movl 12(%ebp),%eax # eax = y cmpl %eax,%edx # x : y jle L9 # if <= goto L9 movl %edx,%eax # eax = x L9: # Done: Skipped when x  y

  5. “Do-While” Loop Example • Use backward branch to continue looping • Only take branch when “while” condition holds C Code Goto Version int fact_do (int x) { int result = 1; do { result *= x; x = x-1; } while (x > 1); return result; } int fact_goto(int x) { int result = 1; loop: result *= x; x = x-1; if (x > 1) goto loop; return result; }

  6. “Do-While” Loop Compilation • Registers %edx x %eax result Goto Version Assembly int fact_goto (int x) { int result = 1; loop: result *= x; x = x-1; if (x > 1) goto loop; return result; } _fact_goto: pushl %ebp # Setup movl %esp,%ebp # Setup movl $1,%eax # eax = 1 movl 8(%ebp),%edx # edx = x L11: imull %edx,%eax # result *= x decl %edx # x-- cmpl $1,%edx # Compare x : 1 jg L11 # if > goto loop movl %ebp,%esp # Finish popl %ebp # Finish ret # Finish

  7. Increasing Addresses Stack Pointer %esp IA32 Stack Stack “Bottom” • Region of memory managed with stack discipline • Grows toward lower addresses • Register %esp indicates lowest stack address • address of top element Stack Grows Down Stack “Top”

  8. Increasing Addresses Stack Pointer %esp IA32 Stack Pushing Stack “Bottom” • Pushing • pushl Src • Fetch operand at Src • Decrement %esp by 4 • Write operand at address given by %esp Stack Grows Down -4 Stack “Top”

  9. Increasing Addresses Stack Pointer %esp IA32 Stack Popping Stack “Bottom” • Popping • popl Dest • Read operand at address given by %esp • Increment %esp by 4 • Write to Dest Stack Grows Down +4 Stack “Top”

  10. Stack Operation Examples pushl %eax popl %edx 0x110 0x110 0x110 0x10c 0x10c 0x10c 0x108 123 0x108 123 0x108 123 0x104 213 0x104 213 %eax 213 %eax 213 %eax 213 %edx 555 %edx 555 %edx 213 555 %esp 0x108 %esp 0x104 0x108 %esp 0x104 0x108

  11. Procedure Control Flow • Use stack to support procedure call and return • Procedure call: call label Push return address on stack; Jump to label • Return address value • Address of instruction beyond call • Example from disassembly 804854e: e8 3d 06 00 00 call 8048b90 <main> 8048553: 50 pushl %eax • Return address = 0x8048553 • Procedure return: • ret Pop address from stack; Jump to address

  12. Procedure Call Example • 804854e: e8 3d 06 00 00 call 8048b90 <main> • 8048553: 50 pushl %eax call 8048b90 0x110 0x110 0x10c 0x10c 0x108 123 0x108 123 0x104 0x8048553 %esp 0x108 %esp 0x108 0x104 %eip 0x804854e %eip 0x804854e 0x8048b90 %eip is program counter

  13. Procedure Return Example • 8048591: c3 ret ret 0x110 0x110 0x10c 0x10c 0x108 123 0x108 123 0x104 0x8048553 0x8048553 %esp 0x104 %esp 0x104 0x108 %eip 0x8048591 %eip 0x8048591 0x8048553 %eip is program counter

  14. Call Chain Example Call Chain • Code Structure • yoo(…) • { • • • • • who(); • • • • • } yoo • who(…) • { • • • • • amI(); • • • • • amI(); • • • • • } who amI amI • amI(…) • { • • • • • amI(); • • • • • } amI amI • Procedure amI recursive

  15. Frame Pointer %ebp Stack Pointer %esp Stack Frames yoo • Contents • Local variables • Return information • Temporary space • Management • Space allocated when enter procedure • “Set-up” code • Deallocated when return • “Finish” code • Pointers • Stack pointer %esp indicates stack top • Frame pointer %ebp indicates start of current frame who amI proc Stack “Top”

  16. Frame Pointer %ebp Stack Pointer %esp Stack Operation • • • Call Chain yoo • yoo(…) • { • • • • • who(); • • • • • } yoo

  17. Frame Pointer %ebp Stack Pointer %esp Stack Operation • • • Call Chain yoo • who(…) • { • • • • • amI(); • • • • • amI(); • • • • • } yoo who who

  18. Frame Pointer %ebp Stack Pointer %esp Stack Operation • • • Call Chain yoo • amI(…) • { • • • • • amI(); • • • • • } yoo who who amI amI

  19. Frame Pointer %ebp Stack Pointer %esp Stack Operation • • • Call Chain yoo • amI(…) • { • • • • • amI(); • • • • • } yoo who who amI amI amI amI

  20. Frame Pointer %ebp Stack Pointer %esp Stack Operation • • • Call Chain yoo • amI(…) • { • • • • • amI(); • • • • • } yoo who who amI amI amI amI amI amI

  21. Frame Pointer %ebp Stack Pointer %esp Stack Operation • • • Call Chain yoo • amI(…) • { • • • • • amI(); • • • • • } yoo who who amI amI amI amI amI

  22. Frame Pointer %ebp Stack Pointer %esp Stack Operation • • • Call Chain yoo • amI(…) • { • • • • • amI(); • • • • • } yoo who who amI amI amI amI

  23. Frame Pointer %ebp Stack Pointer %esp Stack Operation • • • Call Chain yoo • who(…) • { • • • • • amI(); • • • • • amI(); • • • • • } yoo who who amI amI amI

  24. Frame Pointer %ebp Stack Pointer %esp Stack Operation • • • Call Chain yoo • amI(…) • { • • • • • • • • • } yoo who who amI amI amI amI amI

  25. Frame Pointer %ebp Stack Pointer %esp Stack Operation • • • Call Chain yoo • who(…) • { • • • • • amI(); • • • • • amI(); • • • • • } yoo who who amI amI amI amI

  26. Frame Pointer %ebp Stack Pointer %esp Stack Operation • • • Call Chain yoo • yoo(…) • { • • • • • who(); • • • • • } yoo who amI amI amI amI

  27. IA32/Linux Stack Frame • Current Stack Frame (“Top” to Bottom) • Parameters for function about to call • “Argument build” • Local variables • If can’t keep in registers • Saved register context • Old frame pointer • Caller Stack Frame • Return address • Pushed by call instruction • Arguments for this call Caller Frame Arguments Frame Pointer (%ebp) Return Addr Old %ebp Saved Registers + Local Variables Argument Build Stack Pointer (%esp)

  28. Revisiting swap Calling swap from call_swap int zip1 = 4; int zip2 = 5; void main() { swap(&zip1, &zip2); } call_swap: • • • pushl $zip2 # Global Var pushl $zip1 # Global Var call swap • • • • • • Resulting Stack void swap(int *xp, int *yp) { int t0 = *xp; int t1 = *yp; *xp = t1; *yp = t0; } &zip2 &zip1 Rtn adr %esp

  29. Revisiting swap swap: pushl %ebp movl %esp,%ebp subl $16, %esp movl 8(%ebp),%edx movl (%edx),%eax mov1 %eax,-8(%ebp) movl 12(%ebp),%ecx movl (%ecx),%eax movl %eax,-4(%ebp) movl -8(%ebp),%eax movl %eax,(%edx) movl -4(%ebp),%eax movl %eax,(%ecx) leave ret Set Up void swap(int *xp, int *yp) { int t0 = *xp; int t1 = *yp; *xp = t1; *yp = t0; } Body Finish

  30. %ebp • • • yp xp Rtn adr Old %ebp %esp swap Setup #1 Resulting Stack Entering Stack %ebp • • • &zip2 &zip1 Rtn adr %esp swap: pushl %ebp movl %esp,%ebp

  31. swap Setup #2 Resulting Stack Entering Stack %ebp • • • • • • &zip2 yp &zip1 xp Rtn adr %esp Rtn adr %ebp Old %ebp %esp swap: pushl %ebp movl %esp,%ebp

  32. swap Setup #3 Resulting Stack Entering Stack %ebp • • • • • • &zip2 yp &zip1 xp Rtn adr %esp Rtn adr %ebp Old %ebp t1 swap: pushl %ebp movl %esp,%ebp subl $16, %esp t0 %esp

  33. Effect of swap Setup Entering Stack Resulting Stack %ebp • • • • • • Offset (relative to %ebp) &zip2 12 yp &zip1 8 xp Rtn adr %esp 4 Rtn adr %ebp 0 Old %ebp t1 t0 movl 8(%ebp),%eax # get xp . . . Body %esp

  34. swap Finish %ebp • • • swap’s Stack • • • swap’s Stack Offset Offset 12 yp 12 yp 8 xp 8 xp 4 Rtn adr 4 Rtn adr %esp 0 Old %ebp %ebp %esp leave ret

  35. swap Finish %ebp %ebp • • • • • • swap’s Stack Exiting Stack Offset &zip2 12 yp &zip1 %esp 8 xp 4 Rtn adr %esp leave ret

  36. Register Saving Conventions • When procedure yoo calls who: • yoo is the caller, who is the callee • Can Register be Used for Temporary Storage? • Contents of register %edx overwritten by who • yoo: • • • • • movl $15213, %edx • call who • addl %edx, %eax • • • • • ret • who: • • • • • movl 8(%ebp), %edx • addl $91125, %edx • • • • • ret

  37. Register Saving Conventions • When procedure yoo calls who: • yoo is the caller, who is the callee • Can Register be Used for Temporary Storage? • Conventions • “Caller Save” • Caller saves temporary in its frame before calling • “Callee Save” • Callee saves temporary in its frame before using

  38. IA32/Linux Register Usage • Integer Registers • Two have special uses %ebp, %esp • Three managed as callee-save %ebx, %esi, %edi • Old values saved on stack prior to using • Three managed as caller-save %eax, %edx, %ecx • Do what you please, but expect any callee to do so, as well • Register %eax also stores returned value %eax Caller-Save Temporaries %edx %ecx %ebx Callee-Save Temporaries %esi %edi %esp Special %ebp

  39. Pointer Code Recursive Procedure Top-Level Call • Pass pointer to update location void s_helper (int x, int *accum) { if (x <= 1) return; else { int z = *accum * x; *accum = z; s_helper (x-1,accum); } } int sfact(int x) { int val = 1; s_helper(x, &val); return val; }

  40. %ebp Temp. Space val = 1 Unused %esp Creating & Initializing Pointer Initial part of sfact • Using Stack for Local Variable • Variable val must be stored on stack • Need to create pointer to it • Compute pointer as -4(%ebp) • Push on stack as second argument _sfact: pushl %ebp # Save %ebp movl %esp,%ebp # Set %ebp subl $16,%esp # Add 16 bytes movl 8(%ebp),%edx # edx = x movl $1,-4(%ebp) # val = 1 _sfact: pushl %ebp # Save %ebp movl %esp,%ebp # Set %ebp subl $16,%esp # Add 16 bytes movl 8(%ebp),%edx # edx = x movl $1,-4(%ebp) # val = 1 _sfact: pushl %ebp # Save %ebp movl %esp,%ebp # Set %ebp subl $16,%esp # Add 16 bytes movl 8(%ebp),%edx # edx = x movl $1,-4(%ebp) # val = 1 _sfact: pushl %ebp # Save %ebp movl %esp,%ebp # Set %ebp subl $16,%esp # Add 16 bytes movl 8(%ebp),%edx # edx = x movl $1,-4(%ebp) # val = 1 8 x 4 Rtn adr 0 Old %ebp -4 -8 -12 -16 int sfact(int x) { int val = 1; s_helper(x, &val); return val; }

  41. &val x %esp Passing Pointer Calling s_helper from sfact Stack at time of call 8 x leal -4(%ebp),%eax # Compute &val pushl %eax # Push on stack pushl %edx # Push x call s_helper # call movl -4(%ebp),%eax # Return val • • • # Finish leal -4(%ebp),%eax # Compute &val pushl %eax # Push on stack pushl %edx # Push x call s_helper # call movl -4(%ebp),%eax # Return val • • • # Finish leal -4(%ebp),%eax # Compute &val pushl %eax # Push on stack pushl %edx # Push x call s_helper # call movl -4(%ebp),%eax # Return val • • • # Finish 4 Rtn adr %ebp 0 Old %ebp -4 val = 1 val =x! -8 Unused -12 int sfact(int x) { int val = 1; s_helper(x, &val); return val; } -16

  42. accum %edx %eax x Using Pointer void s_helper (int x, int *accum) { • • • int z = *accum * x; *accum = z; • • • } • Register %ecx holds x • Register %edx holds pointer to accum • Use access (%edx) to reference memory accum*x accum*x x %ecx • • • movl %ecx,%eax # z = x imull (%edx),%eax # z *= *accum movl %eax,(%edx) # *accum = z • • •

More Related