Assembly Programmers View CPU Registers PC Condition Codes
Assembly Programmer’s View CPU Registers PC Condition Codes Addresses Code Data Stack Data Instructions Programmer-Visible State § PC: Program counter Address of next instruction § Called “EIP” (IA 32) or “RIP” (x 86 -64) § § Register file § Memory Byte addressable array § Code and user data § Stack to support procedures § Heavily used program data § Condition codes Store status information about most recent arithmetic operation § Used for conditional branching § 1
Complete addressing mode and address computation (leal) 2
Complete Memory Addressing Modes ¢ ¢ Most General Form D(Rb, Ri, S) Mem[Reg[Rb]+S*Reg[Ri]+ D] § D: Constant “displacement” 1, 2, or 4 bytes § Rb: Base register: Any of 8 integer registers § Ri: Index register: Any, except for %esp Unlikely you’d use %ebp, either § S: Scale: 1, 2, 4, or 8 (why these numbers? ) § ¢ ¢ Special Cases (Rb, Ri) Mem[Reg[Rb]+Reg[Ri]] D(Rb, Ri) Mem[Reg[Rb]+Reg[Ri]+D] (Rb, Ri, S) Mem[Reg[Rb]+S*Reg[Ri]] 3
Address Computation Examples %edx 0 x 7000 %ecx 0 x 0200 Expression Address Computation Address 0 x 8(%edx) 0 xf 000 + 0 x 8 0 xf 008 (%edx, %ecx) 0 xf 000 + 0 x 100 0 xf 100 (%edx, %ecx, 4) 0 xf 000 + 4*0 x 100 0 xf 400 0 x 80(, %edx, 2) 2*0 xf 000 + 0 x 80 0 x 1 e 080 4
Address Computation Instruction ¢ leal Src, Dest § Src is address mode expression § Set Dest to address denoted by expression ¢ Uses § Computing addresses without a memory reference E. g. , translation of p = &x[i]; § Computing arithmetic expressions of the form x + k*y § k = 1, 2, 4, or 8 § ¢ Example int mul 12(int x) { return x*12; } Converted to ASM by compiler: leal (%eax, 2), %eax sall $2, %eax ; t <- x+x*2 ; return t<<2 5
Arithmetic operations 6
Some Arithmetic Operations ¢ Two Operand Instructions: Format addl subl imull sarl shrl xorl andl orl ¢ ¢ Computation Src, Dest = Dest + Src Src, Dest = Dest * Src, Dest = Dest << Src Src, Dest = Dest >> Src, Dest = Dest ^ Src, Dest = Dest & Src, Dest = Dest | Src Also called shll Arithmetic Logical Watch out for argument order! No distinction between signed and unsigned int (why? ) 7
Some Arithmetic Operations ¢ One Operand Instructions incl decl negl notl ¢ Dest Dest = Dest + 1 Dest = Dest 1 Dest = ~Dest See the chapter from CSAPP for more instructions 8
Arithmetic Expression Example arith: pushl %ebp %esp, %ebp int arith(int x, int y, int z) movl { movl 8(%ebp), %ecx int t 1 = x+y; movl 12(%ebp), %edx int t 2 = z+t 1; leal (%edx, 2), %eax int t 3 = x+4; sall $4, %eax int t 4 = y * 48; leal 4(%ecx, %eax), %eax int t 5 = t 3 + t 4; addl %ecx, %edx int rval = t 2 * t 5; addl 16(%ebp), %edx return rval; imull %edx, %eax } popl ret %ebp Set Up Body Finish 9
Understanding arith int arith(int x, int y, int z) { int t 1 = x+y; int t 2 = z+t 1; int t 3 = x+4; int t 4 = y * 48; int t 5 = t 3 + t 4; int rval = t 2 * t 5; return rval; } movl leal sall leal addl imull • • Offset • 16 z 12 y 8 x 4 Rtn Addr 0 Old %ebp 8(%ebp), %ecx 12(%ebp), %edx (%edx, 2), %eax $4, %eax 4(%ecx, %eax), %eax %ecx, %edx 16(%ebp), %edx, %eax 10
Understanding arith • • int arith(int x, int y, int z) { int t 1 = x+y; int t 2 = z+t 1; int t 3 = x+4; int t 4 = y * 48; int t 5 = t 3 + t 4; int rval = t 2 * t 5; return rval; } movl leal sall leal addl imull 8(%ebp), %ecx 12(%ebp), %edx (%edx, 2), %eax $4, %eax 4(%ecx, %eax), %eax %ecx, %edx 16(%ebp), %edx, %eax Stack # # # # Offset ecx edx eax eax edx eax • 16 z 12 y 8 x 4 Rtn Addr 0 Old %ebp = x = y*3 *= 16 (t 4) = t 4 +x+4 (t 5) = x+y (t 1) += z (t 2) = t 2 * t 5 (rval) 11
Observations about arith § Instructions in different order int arith(int x, int y, int z) { int t 1 = x+y; int t 2 = z+t 1; int t 3 = x+4; int t 4 = y * 48; int t 5 = t 3 + t 4; int rval = t 2 * t 5; return rval; } movl leal sall leal addl imull 8(%ebp), %ecx 12(%ebp), %edx (%edx, 2), %eax $4, %eax 4(%ecx, %eax), %eax %ecx, %edx 16(%ebp), %edx, %eax # # # # § § ecx edx eax eax edx eax from C code Some expressions require multiple instructions Some instructions cover multiple expressions Get exact same code when compile: (x+y+z)*(x+4+48*y) = x = y*3 *= 16 (t 4) = t 4 +x+4 (t 5) = x+y (t 1) += z (t 2) = t 2 * t 5 (rval) 12
Assembly Programmer’s View CPU Registers PC Condition Codes Addresses Code Data Stack Data Instructions Programmer-Visible State § PC: Program counter Address of next instruction § Called “EIP” (IA 32) or “RIP” (x 86 -64) § § Register file § Memory Byte addressable array § Code and user data § Stack to support procedures § Heavily used program data § Condition codes Store status information about most recent arithmetic operation § Used for conditional branching § 13
Control: Conditon codes 14
Processor State (IA 32, Partial) ¢ Information about currently executing program § Temporary data ( %eax, … ) § Location of runtime stack ( %ebp, %esp ) § Location of current code control point ( %eip, … ) § Status of recent tests ( CF, ZF, SF, OF ) %eax %ecx %edx %ebx General purpose registers %esi %edi %esp %ebp Current stack top %eip Instruction pointer Current stack frame CF ZF SF OF Condition codes 15
Condition Codes (Implicit Setting) ¢ Single bit registers §CF §ZF ¢ Carry Flag (for unsigned) SF Sign Flag (for signed) Zero Flag OF Overflow Flag (for signed) Implicitly set (think of it as side effect) by arithmetic operations Example: addl/addq Src, Dest ↔ t = a+b 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) ¢ Not set by lea instruction 16
Condition Codes (Explicit Setting: Compare) ¢ Explicit Setting by Compare Instruction §cmpl Src 2, Src 1 §cmpl b, a like computing a-b without setting destination §CF set if carry out from most significant bit (used for unsigned comparisons) §ZF set if a == b §SF 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) 17
Condition Codes (Explicit Setting: Test) ¢ Explicit Setting by Test instruction §testl Src 2, Src 1 testl b, a like computing a&b without setting destination §Sets condition codes based on value of Src 1 & Src 2 §Useful to have one of the operands be a mask §ZF set when a&b == 0 §SF set when a&b < 0 18
Reading Condition Codes ¢ Set. X Instructions § Set single byte based on combinations of condition codes Set. X sete setne sets setns setge setle seta setb Condition ZF ~ZF SF ~(SF^OF)&~ZF ~(SF^OF)|ZF ~CF&~ZF CF Description Equal / Zero Not Equal / Not Zero Negative Nonnegative Greater (Signed) Greater or Equal (Signed) Less or Equal (Signed) Above (unsigned) Below (unsigned) 19
Reading Condition Codes (Cont. ) ¢ %eax %ah %al %ecx %ch %cl § Does not alter remaining 3 bytes § Typically use movzbl to finish job %edx %dh %dl int gt (int x, int y) { return x > y; } %ebx %bh %bl Set. X Instructions: § Set single byte based on combination of condition codes ¢ One of 8 addressable byte registers Body movl 12(%ebp), %eax cmpl %eax, 8(%ebp) setg %al movzbl %al, %eax %esi %edi # # eax = y Compare x : y al = x > y Zero rest of %eax %esp %ebp 20
Conditional branches and moves 21
Conditional branches and moves 22
Jumping ¢ j. X Instructions § Jump to different part of code depending on condition codes j. X 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) 23
Conditional Branch Example int absdiff(int x, int y) { int result; if (x > y) { result = x-y; } else { result = y-x; } return result; } absdiff: pushl %ebp movl %esp, %ebp movl 8(%ebp), %edx movl 12(%ebp), %eax cmpl %eax, %edx jle. L 6 subl %eax, %edx movl %edx, %eax jmp. L 7. L 6: subl %edx, %eax. L 7: popl %ebp ret Setup Body 1 Body 2 a Body 2 b Finish 24
Conditional Branch Example (Cont. ) int goto_ad(int x, int y) { int result; if (x <= y) goto Else; result = x-y; goto Exit; Else: result = y-x; Exit: return result; } ¢ C allows “goto” as means of transferring control § Closer to machine-level absdiff: pushl %ebp movl %esp, %ebp movl 8(%ebp), %edx movl 12(%ebp), %eax cmpl %eax, %edx jle. L 6 subl %eax, %edx movl %edx, %eax jmp. L 7. L 6: subl %edx, %eax. L 7: popl %ebp ret Setup Body 1 Body 2 a Body 2 b Finish programming style ¢ Generally considered 25
GO TO statements considered harmful 26
Conditional Branch Example (Cont. ) int goto_ad(int x, int y) { int result; if (x <= y) goto Else; result = x-y; goto Exit; Else: result = y-x; Exit: return result; } absdiff: pushl %ebp movl %esp, %ebp movl 8(%ebp), %edx movl 12(%ebp), %eax cmpl %eax, %edx jle. L 6 subl %eax, %edx movl %edx, %eax jmp. L 7. L 6: subl %edx, %eax. L 7: popl %ebp ret Setup Body 1 Body 2 a Body 2 b Finish 27
Conditional Branch Example (Cont. ) int goto_ad(int x, int y) { int result; if (x <= y) goto Else; result = x-y; goto Exit; Else: result = y-x; Exit: return result; } absdiff: pushl %ebp movl %esp, %ebp movl 8(%ebp), %edx movl 12(%ebp), %eax cmpl %eax, %edx jle. L 6 subl %eax, %edx movl %edx, %eax jmp. L 7. L 6: subl %edx, %eax. L 7: popl %ebp ret Setup Body 1 Body 2 a Body 2 b Finish 28
Conditional Branch Example (Cont. ) int goto_ad(int x, int y) { int result; if (x <= y) goto Else; result = x-y; goto Exit; Else: result = y-x; Exit: return result; } absdiff: pushl %ebp movl %esp, %ebp movl 8(%ebp), %edx movl 12(%ebp), %eax cmpl %eax, %edx jle. L 6 subl %eax, %edx movl %edx, %eax jmp. L 7. L 6: subl %edx, %eax. L 7: popl %ebp ret Setup Body 1 Body 2 a Body 2 b Finish 29
Loops 30
“Do-While” Loop Example C Code int pcount_do(unsigned x) { int result = 0; do { result += x & 0 x 1; x >>= 1; } while (x); return result; } Goto Version int pcount_do(unsigned x) { int result = 0; loop: result += x & 0 x 1; x >>= 1; if (x) goto loop; return result; } Count number of 1’s in argument x (“popcount”) ¢ Use conditional branch to either continue looping or to exit loop ¢ 31
“Do-While” Loop Compilation Goto Version int pcount_do(unsigned x) { int result = 0; loop: result += x & 0 x 1; x >>= 1; if (x) goto loop; return result; } Registers: %edx x %ecx result ¢ movl. L 2: movl andl addl shrl jne $0, %ecx %edx, %eax $1, %eax, %ecx %edx. L 2 # result = 0 # loop: # # t = x & 1 result += t x >>= 1 If !0, goto loop 32
General “Do-While” Translation C Code do Body while (Test); ¢ Body: { } ¢ Goto Version loop: Body if (Test) goto loop Statement 1; Statement 2; … Statementn; Test returns integer § = 0 interpreted as false § ≠ 0 interpreted as true 33
“While” Loop Example C Code int pcount_while(unsigned x) { int result = 0; while (x) { result += x & 0 x 1; x >>= 1; } return result; } ¢ Goto Version int pcount_do(unsigned x) { int result = 0; if (!x) goto done; loop: result += x & 0 x 1; x >>= 1; if (x) goto loop; done: return result; } Is this code equivalent to the do-while version? § Must jump out of loop if test fails 34
General “While” Translation While version while (Test) Body Do-While Version if (!Test) goto done; do Body while(Test); done: Goto Version if (!Test) goto done; loop: Body if (Test) goto loop; done: 35
“For” Loop Example C Code #define WSIZE 8*sizeof(int) int pcount_for(unsigned x) { int i; int result = 0; for (i = 0; i < WSIZE; i++) { unsigned mask = 1 << i; result += (x & mask) != 0; } return result; } ¢ Is this code equivalent to other versions? 36
“For” Loop While Loop For Version for (Init; Test; Update ) Body While Version Init; while (Test ) { Body Update; } 37
“For” Loop Form General Form for (Init; Test; Update ) Body Init i = 0 Test i < WSIZE Update for (i = 0; i < WSIZE; i++) { unsigned mask = 1 << i; result += (x & mask) != 0; } i++ Body { unsigned mask = 1 << i; result += (x & mask) != 0; } 38
“For” Loop … Goto For Version for (Init; Test; Update ) Body Init; if (!Test) goto done; loop: Body Update if (Test) goto loop; done: While Version Init; while (Test ) { Body Update; } Init; if (!Test) goto done; do Body Update while(Test); done: 39
“For” Loop Conversion Example C Code #define WSIZE 8*sizeof(int) int pcount_for(unsigned x) { int i; int result = 0; for (i = 0; i < WSIZE; i++) { unsigned mask = 1 << i; result += (x & mask) != 0; } return result; } ¢ Initial test can be optimized away Goto Version int pcount_for_gt(unsigned x) { int i; int result = 0; Init i = 0; if (!(i < WSIZE)) !Test goto done; loop: Body { unsigned mask = 1 << i; result += (x & mask) != 0; } i++; Update if (i < WSIZE) Test goto loop; done: return result; } 40
Assembly Programmer’s View CPU Registers PC Condition Codes Addresses Code Data Stack Data Instructions Programmer-Visible State § PC: Program counter Address of next instruction § Called “EIP” (IA 32) or “RIP” (x 86 -64) § § Register file § Memory Byte addressable array § Code and user data § Stack to support procedures § Heavily used program data § Condition codes Store status information about most recent arithmetic operation § Used for conditional branching § 41
Summary ¢ So far § § § ¢ Complete addressing mode, address computation (leal) Arithmetic operations Control: Condition codes Conditional branches & conditional moves Loops Coming up! § § Switch statements Stack Call / return Procedure call discipline 42
Today Switch statements ¢ IA 32 Procedures ¢ § Stack Structure § Calling Conventions § Illustrations of Recursion & Pointers 43
IA 32 Stack Region of memory managed with stack discipline ¢ Grows toward lower addresses Stack “Bottom” ¢ ¢ Increasing Addresses Register %esp contains lowest stack address Stack Grows Down § address of “top” element Stack Pointer: %esp Stack “Top” 44
IA 32 Stack: Push ¢ Stack “Bottom” pushl Src § Fetch operand at Src § Decrement %esp by 4 § Write operand at address given by %esp Stack Pointer: %esp Increasing Addresses Stack Grows Down -4 Stack “Top” 45
IA 32 Stack: Pop Stack “Bottom” Increasing Addresses Stack Pointer: %esp +4 Stack Grows Down Stack “Top” 46
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: § Address of the next instruction right after call § Example from disassembly 804854 e: 8048553: e 8 3 d 06 00 00 50 call pushl 8048 b 90 <main> %eax § Return address = 0 x 8048553 ¢ Procedure return: ret § Pop address from stack § Jump to address 47
Procedure Call Example 804854 e: 8048553: e 8 3 d 06 00 00 50 call pushl 8048 b 90 <main> %eax call 8048 b 90 0 x 110 0 x 10 c 0 x 108 %esp 123 0 x 108 %eip 0 x 804854 e %eip: program counter 0 x 108 123 0 x 104 0 x 8048553 %esp 0 x 104 %eip 0 x 8048 b 90 48
Procedure Return Example 8048591: c 3 ret %eip: program counter 0 x 110 0 x 10 c 0 x 108 123 0 x 104 0 x 8048553 %esp 0 x 104 %esp 0 x 108 %eip 0 x 8048591 %eip 0 x 8048553 49
Stack-Based Languages ¢ Languages that support recursion § e. g. , C, Pascal, Java § Code must be “Reentrant” Multiple simultaneous instantiations of single procedure § Need some place to store state of each instantiation § Arguments § Local variables § Return pointer § ¢ Stack discipline § State for given procedure needed for limited time From when called to when return § Callee returns before caller does § ¢ Stack allocated in Frames § state for single procedure instantiation 50
Call Chain Example yoo(…) { • • who(); • • } Example Call Chain yoo who(…) { • • • am. I(); • • • } who am. I(…) { • • am. I(); • • } am. I Procedure am. I() is recursive 51
Stack Frames ¢ Previous Frame Contents § Local variables § Return information § Temporary space Frame Pointer: %ebp Frame for proc Stack Pointer: %esp ¢ Management § Space allocated when enter procedure Stack “Top” “Set-up” code § Deallocated when return § “Finish” code § 52
Stack Example yoo(…) { • • who(); • • } yoo %ebp yoo who am. I %esp am. I 53
Stack Example yoo(…) { who(…) • { • • am. I(); who(); • • • am. I(); • • • } } yoo yoo who am. I %ebp am. I %esp who am. I 54
Stack Example yoo(…) { who(…) • { am. I(…) • • { am. I(); who(); • • am. I(); • } • } yoo yoo who am. I %ebp am. I %esp am. I 55
Stack Example yoo(…) { who(…) • { am. I(…) • • { am. I(); who(); am. I(…) • • { • • • am. I(); • • } • am. I(); • } yoo yoo who am. I %ebp am. I %esp 56
Stack Example yoo(…) { who(…) • { am. I(…) • • { am. I(); who(); am. I(…) • • { • • • am. I(); • • } • am. I(); • } yoo yoo who am. I %ebp am. I %esp 58
Stack Example yoo(…) { who(…) • { am. I(…) • • { am. I(); who(); • • am. I(); • } • } yoo yoo who am. I %ebp am. I %esp am. I 59
Stack Example yoo(…) { who(…) • { • • am. I(); who(); • • • am. I(); • • • } } yoo yoo who am. I %ebp am. I %esp who am. I 60
Stack Example yoo(…) { who(…) • { am. I(…) • • { am. I(); who(); • • am. I(); • } • } yoo yoo who am. I %ebp am. I %esp am. I 61
Stack Example yoo(…) { who(…) • { • • am. I(); who(); • • • am. I(); • • • } } yoo yoo who am. I %ebp am. I %esp who am. I 62
Stack Example yoo(…) { • • who(); • • } yoo %ebp yoo who am. I %esp am. I 63
IA 32/Linux Stack Frame ¢ Current Stack Frame (“Top” to Bottom) § “Argument build: ” Caller Frame Parameters for function about to call § Local variables If can’t keep in registers Frame pointer %ebp § Saved register context § Old frame pointer ¢ Caller Stack Frame § Return address Pushed by call instruction § Arguments for this call § Stack pointer %esp Arguments Return Addr Old %ebp Saved Registers + Local Variables Argument Build 64
Revisiting swap Calling swap from call_swap int course 1 = 15213; int course 2 = 18243; void call_swap() { swap(&course 1, &course 2); } void swap(int *xp, int *yp) { int t 0 = *xp; int t 1 = *yp; *xp = t 1; *yp = t 0; } call_swap: • • • subl movl call • • • $8, %esp $course 2, 4(%esp) $course 1, (%esp) swap Resulting Stack %esp &course 2 subl &course 1 %esp Rtn adr %esp call 65
Revisiting swap void swap(int *xp, int *yp) { int t 0 = *xp; int t 1 = *yp; *xp = t 1; *yp = t 0; } swap: pushl %ebp movl %esp, %ebp pushl %ebx movl movl 8(%ebp), %edx 12(%ebp), %ecx (%edx), %ebx (%ecx), %eax, (%edx) %ebx, (%ecx) popl ret %ebx %ebp Set Up Body Finish 66
swap Setup #1 Entering Stack Resulting Stack %ebp • • • &course 2 yp &course 1 xp Rtn adr %esp Rtn adr Old %ebp %esp swap: pushl %ebp movl %esp, %ebp pushl %ebx 67
swap Setup #2 Entering Stack Resulting Stack %ebp • • • &course 2 yp &course 1 xp Rtn adr %esp Rtn adr Old %ebp %esp swap: pushl %ebp movl %esp, %ebp pushl %ebx 68
swap Setup #3 Entering Stack Resulting Stack %ebp • • • &course 2 yp &course 1 xp Rtn adr %esp Rtn adr Old %ebp Old %ebx %esp swap: pushl %ebp movl %esp, %ebp pushl %ebx 69
swap Body Entering Stack Resulting Stack %ebp • • • Offset relative to %ebp • • • &course 2 12 yp &course 1 8 xp 4 Rtn adr %esp movl 8(%ebp), %edx movl 12(%ebp), %ecx. . . Old %ebp Old %ebx %esp # get xp # get yp 70
swap Finish Stack Before Finish Resulting Stack %ebp • • • popl %ebx %ebp • • • yp yp xp xp Rtn adr Old %ebp Old %ebx %esp ¢ %esp Observation § Saved and restored register %ebx § Not so for %eax, %ecx, %edx 71
Disassembled swap 08048384 <swap>: 8048384: 55 8048385: 89 e 5 8048387: 53 8048388: 8 b 55 08 804838 b: 8 b 4 d 0 c 804838 e: 8 b 1 a 8048390: 8 b 01 8048392: 89 02 8048394: 89 19 8048396: 5 b 8048397: 5 d 8048398: c 3 push mov mov pop ret %ebp %esp, %ebp %ebx 0 x 8(%ebp), %edx 0 xc(%ebp), %ecx (%edx), %ebx (%ecx), %eax, (%edx) %ebx, (%ecx) %ebx %ebp Calling Code 80483 b 4: 80483 bc: 80483 c 3: 80483 c 8: 80483 c 9: movl call leave ret $0 x 8049658, 0 x 4(%esp) # $0 x 8049654, (%esp) # 8048384 <swap> # # # Copy &course 2 Copy &course 1 Call swap Prepare to return Return 72
Assembly Programmer’s View CPU Registers PC Condition Codes Addresses Code Data Stack Data Instructions Programmer-Visible State § PC: Program counter Address of next instruction § Called “EIP” (IA 32) or “RIP” (x 86 -64) § § Register file § Memory Byte addressable array § Code and user data § Stack to support procedures § Heavily used program data § Condition codes Store status information about most recent arithmetic operation § Used for conditional branching § 74
Creating and Initializing Local Variable int add 3(int x) { int localx = x; incrk(&localx, 3); return localx; } ¢ Variable localx must be stored on stack § Because: Need to create pointer to it ¢ Compute pointer as -4(%ebp) First part of add 3: pushl%ebp movl %esp, %ebp subl $24, %esp # Alloc. 24 bytes movl 8(%ebp), %eax movl %eax, -4(%ebp)# Set localx to x 8 x 4 Rtn adr 0 Old %ebp -4 %ebp localx = x -8 -12 Unused -16 -20 -24 %esp 75
Creating Pointer as Argument int add 3(int x) { int localx = x; incrk(&localx, 3); return localx; } ¢ Use leal instruction to compute address of localx Middle part of add 3 movl leal movl call $3, 4(%esp) # 2 nd arg = 3 -4(%ebp), %eax# &localx %eax, (%esp) # 1 st arg = &localx incrk 8 x 4 Rtn adr 0 Old %ebp -4 %ebp localx -8 -12 Unused -16 -20 -24 3 %esp+4 %esp 76
Retrieving local variable int add 3(int x) { int localx = x; incrk(&localx, 3); return localx; } ¢ Retrieve localx from stack as return value Final part of add 3 movl -4(%ebp), %eax # Return val= localx leave ret 8 x 4 Rtn adr 0 Old %ebp -4 %ebp localx -8 -12 Unused -16 -20 -24 %esp 77
So what about these arrays? int a[16]; char *c; c = (char *)malloc(256); How are arrays actually represented in assembly? 79
Basic Data Types ¢ Integral § Stored & operated on in general (integer) registers § Signed vs. unsigned depends on instructions used Intel byte word double word quad word ¢ ASM b w l q Bytes 1 2 4 8 C [unsigned] char short int long int (x 86 -64) Floating Point § Stored & operated on in floating point registers Intel Single Double Extended ASM s l t Bytes 4 8 10/12/16 C float double long double 80
Array Allocation ¢ Basic Principle T A[L]; § Array of data type T and length L § Contiguously allocated region of L * sizeof(T) bytes char string[12]; x x + 12 int val[5]; x x+4 x+8 x + 12 x + 16 x + 20 double a[3]; x x+8 x + 16 x + 24 IA 32 char *p[3]; x x+4 x+8 x + 12 x 86 -64 x x+8 x + 16 x + 24 81
Array Access ¢ Basic Principle T A[L]; § Array of data type T and length L § Identifier A can be used as a pointer to array element 0: Type T* 1 int val[5]; x ¢ Reference val[4] val+1 &val[2] val[5] *(val+1) val + i 5 x+4 2 x+8 Type? Value? int int 3 x x+4 x+8 ? ? 5 x + 4 i * * 1 x + 12 3 x + 16 x + 20 WATWAT 82
Array Example #define ZLEN 5 typedef int zip_dig[ZLEN]; zip_dig cmu = { 1, 5, 2, 1, 3 }; zip_dig mit = { 0, 2, 1, 3, 9 }; zip_dig ucb = { 9, 4, 7, 2, 0 }; 1 zip_dig cmu; 16 20 0 zip_dig mit; 36 56 ¢ 2 24 2 40 9 zip_dig ucb; ¢ 5 28 1 44 4 60 1 32 3 48 7 64 3 9 52 2 68 36 56 0 72 76 Declaration “zip_dig cmu” equivalent to “int cmu[5]” Example arrays were allocated in successive 20 byte blocks § Not guaranteed to happen in general 83
Array Access - Idea 4 element array of ints Array start %edx Offset %eax 84
Array Accessing Example 1 zip_dig cmu; 16 5 20 2 24 1 28 int get_digit (zip_dig z, int dig) { return z[dig]; } 32 n IA 32 # %edx = z # %eax = dig movl (%edx, %eax, 4), %eax 3 n # z[dig] n n 36 Register %edx contains starting address of array Register %eax contains array index Desired digit at 4*%eax + %edx Use memory reference (%edx, %eax, 4) 85
Array Loop Example (IA 32) void zincr(zip_dig z) { int i; for (i = 0; i < ZLEN; i++) z[i]++; } # edx movl. L 4: addl cmpl jne = z $0, %eax # %eax = i # loop: $1, (%edx, %eax, 4) # z[i]++ $1, %eax # i++ $5, %eax # i: 5. L 4 # if !=, goto loop 86
Pointer Loop Example (IA 32) void zincr_p(zip_dig z) { int *zend = z+ZLEN; do { (*z)++; z++; } while (z != zend); } # edx movl. L 8: addl cmpl jne = z = vz $0, %eax $1, (%edx, %eax) $4, %eax $20, %eax. L 8 void zincr_v(zip_dig z) { void *vz = z; int i = 0; do { (*((int *) (vz+i)))++; i += ISIZE; } while (i != ISIZE*ZLEN); } # i = 0 # loop: # Increment vz+i # i += 4 # Compare i: 20 # if !=, goto loop 87
How do we fit a 2 D matrix into memory? Row-major ordering Q: How do we find cell (i, j)? a b c d WAT e f g h i 8 88
89
Nested Array Example #define PCOUNT 4 zip_dig pgh[PCOUNT] = {{1, 5, 2, 0, 6}, {1, 5, 2, 1, 3 }, {1, 5, 2, 1, 7 }, {1, 5, 2, 2, 1 }}; zip_dig pgh[4]; 1 5 2 0 6 1 5 2 1 3 1 5 2 1 7 1 5 2 2 1 76 ¢ 96 116 136 156 “zip_dig pgh[4]” equivalent to “int pgh[4][5]” § Variable pgh: array of 4 elements, allocated contiguously § Each element is an array of 5 int’s, allocated contiguously ¢ Important: “Row-Major” ordering of all elements guaranteed 90
Multidimensional (Nested) Arrays ¢ Declaration T A[R][C]; § 2 D array of data type T § R rows, C columns § Type T element requires K bytes ¢ Array Size a A[0][0] • • • b • • • c A[0][C-1] d e f g h i • • • A[R-1][0] • • • A[R-1][C-1] § R * C * K bytes ¢ Arrangement § Row-Major Ordering int A[R][C]; A [0] A A • • • [0] [1] [C-1] [0] A • • • [1] [C-1] • • • A A [R-1] • • • [R-1] [0] [C-1] 4*R*C Bytes 91
Nested Array Row Access ¢ Row Vectors § A[i] is array of C elements § Each element of type T requires K bytes § Starting address A + i * (C * K) int A[R][C]; A[0] A • • • A[i] A [0] [C-1] • • • A [i] [0] • • • A+i*C*4 A[R-1] A [i] [C-1] • • • A [R-1] [0] • • • A [R-1] [C-1] A+(R-1)*C*4 92
Nested Array Row Access Code int *get_pgh_zip(int index) { return pgh[index]; } #define PCOUNT 4 zip_dig pgh[PCOUNT] = {{1, 5, 2, 0, 6}, {1, 5, 2, 1, 3 }, {1, 5, 2, 1, 7 }, {1, 5, 2, 2, 1 }}; # %eax = index leal (%eax, 4), %eax # 5 * index leal pgh(, %eax, 4), %eax # pgh + (20 * index) ¢ Row Vector § pgh[index] is array of 5 int’s § Starting address pgh+20*index ¢ IA 32 Code § Computes and returns address § Compute as pgh + 4*(index+4*index) 93
Nested Array Row Access ¢ Array Elements § A[i][j] is element of type T, which requires K bytes § Address A + i * (C * K) + j * K = A + (i * C + j)* K int A[R][C]; A[0] A • • • A[i] A [0] [C-1] • • • • A [i] [j] A[R-1] • • • A+i*C*4 • • • A [R-1] [0] • • • A [R-1] [C-1] A+(R-1)*C*4 A+i*C*4+j*4 94
Nested Array Row Access ¢ Array Elements § A[i][j] is element of type T, which requires K bytes § Address A + i * (C * K) + j * K = A + (i * C + j)* K A[i][j] == int A[R][C]; A[0] A • • • A[i] A [0] [C-1] A + (i*C + j)*K • • • • A [i] [j] • • • A+i*C*4 A[R-1] • • • A [R-1] [0] • • • A [R-1] [C-1] A+(R-1)*C*4 A+i*C*4+j*4 95
Assembly Programmer’s View CPU Registers PC Condition Codes Addresses Code Data Stack Data Instructions Programmer-Visible State § PC: Program counter Address of next instruction § Called “EIP” (IA 32) or “RIP” (x 86 -64) § § Register file § Memory Byte addressable array § Code and user data § Stack to support procedures § Heavily used program data § Condition codes Store status information about most recent arithmetic operation § Used for conditional branching § 100
- Slides: 94