200 likes | 341 Views
Outline Recursive procedure Complex data structures Arrays Structs Unions Function pointer Reminders Lab 2: Wed. 11:59PM Lab 3: start early. Minglong Shao E-mail: shaoml+213@cs.cmu.edu Office hours: Thursdays 5-6PM Wean Hall 1315. Recitation 3.
E N D
Outline Recursive procedure Complex data structures Arrays Structs Unions Function pointer Reminders Lab 2: Wed. 11:59PM Lab 3: start early Minglong Shao E-mail: shaoml+213@cs.cmu.edu Office hours: Thursdays 5-6PM Wean Hall 1315 Recitation 3
Recursive procedure example: Fibonacci 0x8048420 push %ebp 0x8048421 mov %esp,%ebp 0x8048423 sub $0x10,%esp 0x8048426 push %esi 0x8048427 push %ebx 0x8048428 mov 0x8(%ebp),%ebx 0x804842b cmp $0x2,%ebx 0x804842e jg 0x8048437 0x8048430 mov $0x1,%eax 0x8048435 jmp 0x8048453 0x8048437 add $0xfffffff4,%esp 0x804843a lea 0xfffffffe(%ebx),%eax 0x804843d push %eax 0x804843e call 0x8048420 <fibo> 0x8048443 mov %eax,%esi 0x8048445 add $0xfffffff4,%esp 0x8048448 lea 0xffffffff(%ebx),%eax 0x804844b push %eax 0x804844c call 0x8048420 <fibo> 0x8048451 add %esi,%eax 0x8048453 lea 0xffffffe8(%ebp),%esp 0x8048456 pop %ebx 0x8048457 pop %esi 0x8048458 mov %ebp,%esp 0x804845a pop %ebp 0x804845b ret int fibo (int n) { int result; if (n <= 2) result = 1; else result = fibo(n-2) + fibo(n-1); return result; }
%ebp %esp Stack Frame <fibo> 0x8048420 push %ebp 0x8048421 mov %esp,%ebp 0x8048423 sub $0x10,%esp 0x8048426 push %esi 0x8048427 push %ebx . . . . . . 0x8048453 lea 0xffffffe8(%ebp),%esp 0x8048456 pop %ebx 0x8048457 pop %esi 0x8048458 mov %ebp,%esp 0x804845a pop %ebp 0x804845b ret x rtrn addr old %ebp Stack at this point old %esi old %ebx
Write Comments For Body 0x8048428 mov 0x8(%ebp),%ebx # ebx = x 0x804842b cmp $0x2,%ebx # if (x>2) 0x804842e jg 0x8048437 # goto L1 0x8048430 mov $0x1,%eax # eax = 1 0x8048435 jmp 0x8048453 # goto L2 0x8048437 add $0xfffffff4,%esp # L1: 0x804843a lea 0xfffffffe(%ebx),%eax # 0x804843d push %eax # push x-2 0x804843e call 0x8048420 <fibo> # call fibo 0x8048443 mov %eax,%esi # esi = eax 0x8048445 add $0xfffffff4,%esp # 0x8048448 lea 0xffffffff(%ebx),%eax # 0x804844b push %eax # push x-1 0x804844c call 0x8048420 <fibo> # call fibo 0x8048451 add %esi,%eax # eax += esi 0x8048453 . . . # L2:
fibo(3) %ebp %esp %ebp %esp %ebp %esp Stack Changes of fibo(3) return call fibo(1) fibo(3) fibo(3) 1 1 0x8048443 fibo(1)
%esp %ebp %esp %ebp %esp %ebp Stack Changes of fibo(3) return call fibo(2) fibo(3) fibo(3) fibo(3) 1 1 1 2 2 0x8048451 fibo(2)
40 44 48 52 56 60 1 5 2 1 3 Arrays • Allocated as contiguous blocks of memory int cmu[5] = {…}; /*cmu begins at address 40*/ • Address Computation Example cmu[0] 40+0*sizeof(int) = 40 cmu[3] 40+3*sizeof(int) = 52 cmu[i] 40+i*sizeof(int) = 40 + 4*I • “x = cmu[i]” in assembly code #%edx = cmu, %eax = i movl (%edx, %eax, 4), %eax #%eax stores x
Nested arrays • Declaration • T A[R][C]; • Array of data type T • A[i] is an array of C elements • R rows • C columns • Type T element requires K bytes • Array Size • R * C * Kbytes • Arrangement • Row-major ordering
A[0] A[i] A[R-1] A [i] [0] • • • A [R-1] [0] • • • A [0] [0] • • • A [0] [C-1] A [R-1] [C-1] A [i] [C-1] Nested arrays: in terms of Memory int A[R][C]; Like a matrix Row-major ordering • • • • • • A A+i*C*4 A+(R-1)*C*4 Starting address of A[i]
Nested arrays: in terms of code • Suppose we have “int pgh[4][5]” • Compute address of pgh[index][dig]: phg + index*sizeof(int)*5 + sizeof(int)*dig Assembly code: # %ecx = dig # %eax = index leal 0(,%ecx,4),%edx # 4*dig leal (%eax,%eax,4),%eax # 5*index movl pgh(%edx,%eax,4),%eax # *(pgh + 4*dig + 20*index)
i a p 0 4 16 Structures • Contiguously-allocated region of memory • Refer to members within structure by names • Members may be of different types • Example: struct rec { int i; int a[3]; int *p; }; Memory Layout
i a p 0 4 16 Structures - Code • Offset of each structure member determined at compile time r struct rec { int i; int a[3]; int *p; }; r + 4 + 4*idx int * find_a (struct rec *r, int idx){ return &r->a[idx]; } # %ecx = idx # %edx = r leal 0(,%ecx,4),%eax # 4*idx leal 4(%eax,%edx),%eax # r+4*idx+4
Multiple of 8 Multiple of 8 Multiple of 4 Multiple of 8 c i[0] i[1] v p+0 p+4 p+8 p+16 p+24 Alignment • Offsets Within Structure • Must satisfy element’s alignment requirement • Overall Structure Placement • Each structure has alignment requirement K • Largest alignment of any element • Initial address & structure length must be multiples of K • Example (under Windows): • K = 8, due to ”double” element struct S1 { char c; int i[2]; double v; } *p;
c i[0] i[1] v up+0 up+4 up+8 Unions • Overlay union elements • Allocate according to largest element • Can only use one field at a time union U1 { char c; int i[2]; double v; } *up;
Homework problem 3.36 A piece of C code Assembly code of test: typedef struct { int left; a_struct a[CNT]; int right; } b_struct; void test(int i, b_struct *bp) { int n = bp->left + bp->right; a_struct *ap = &bp->a[i]; ap->x[ap->idx] = n; } • push %ebp • mov %esp, %ebp • push %ebx • mov 0x8(%ebp), %eax • mov 0xc(%ebp), %ecx • lea (%eax,%eax,4),%eax • lea 0x4(%ecx,%eax,4),%eax • mov (%eax), %edx • shl $0x2, %edx • mov 0xb8(%ecx), %ebx • add (%ecx), %ebx • mov %ebx,0x4(%ebx,%eax,1) • pop %ebx • mov %ebp, %esp • pop %ebp • ret Suppose a_struct only has elements: x and idx
Homework problem 3.36 • Question: • Find out the value of CNT • Complete declaration of a_struct
Homework problem 3.36 void test(int i, b_struct *bp){ int n = bp->left + bp->right; a_struct *ap = &bp->a[i]; ap->x[ap->idx] = n; } • push %ebp • mov %esp, %ebp • push %ebx • mov 0x8(%ebp), %eax # %eax = i • mov 0xc(%ebp), %ecx # %ecx = bp • lea (%eax,%eax,4),%eax # • lea 0x4(%ecx,%eax,4),%eax # %eax = bp+4+4*(5*i) = ap • mov (%eax), %edx # %edx = *(%eax) = idx • shl $0x2, %edx # %edx = %edx * 4 = idx * 4 • mov 0xb8(%ecx), %ebx # • add (%ecx), %ebx # %ebx = *(bp)+*(bp+0xb8)= n • mov %ebx,0x4(%edx,%eax,1) # *(ap + 4 + idx*4) = %ebx • pop %ebx • mov %ebp, %esp • pop %ebp • ret
Answer: CNT = 9 typedef struct { int idx; int x[4]; } a_struct; bp+4 left idx x[0] x[1] x[2] x[3] idx x[0] x[1] x[2] x[3] right …… bp->a[8] bp+0 bp->a[0] bp+184
Function pointer (C code) void (*pfunc) (char *message); /*declaration*/ void myprint(char *message) { printf(“my message: %s\n", message); } void message(void (*pfunc)(char *message), char *str) { pfunc(str); } int main(int argc, char* argv[]) { message(myprint, “hello world”); return 0; }
Function pointer (assembly code) main: push %ebp mov %esp, %ebp sub $0x8, %esp and $0xfffffff0, %esp mov $0x0, %eax sub %eax, %esp sub $0x8, %esp push 0x8048444 push 0x8048328 call 0x8048343 <message> add $0x10, %esp mov $0x0, %eax leave ret message: push %ebp mov %esp, %ebp sub $0x8, %esp sub $0xc, %esp push 0xc(%ebp) mov 0x8(%ebp), %eax call *%eax add $0x10, %esp leave ret myprint: 0x8048328 push %ebp 0x8048329 mov %esp, %ebp Function pointer is starting address of a function