130 likes | 278 Views
C structures and Compilation to IA32. If you’re not careful, data in structures can be copied multiple times Doesn’t matter for small structures, but…. Simple example. typedef struct p { int x, y; } point; void make() { point p, q; p.x = 1; p.y = 2; q = move(p, 3, 4); }
E N D
C structures and Compilation to IA32 If you’re not careful, data in structures can be copied multiple times Doesn’t matter for small structures, but…
Simple example typedefstruct p { int x, y; } point; void make() { point p, q; p.x = 1; p.y = 2; q = move(p, 3, 4); } point move(point p, int dx, intdy) { p.x += dx; p.y += dy; return p; }
Original C code void make() { point p, q; p.x = 1; p.y = 2; q = move(p, 3, 4); } IA32 code make: pushl %ebp movl %esp, %ebp subl $44, %esp movl $1, -8(%ebp) # p.x = 1 movl $2, -4(%ebp) # p.y = 2 leal -24(%ebp), %eax # &c in %eax movl $4, 16(%esp) # dy is 5thparam (3rd in C) movl $3, 12(%esp) # dx is 4thparam (2nd in C) movl -8(%ebp), %edx movl -4(%ebp), %ecx movl %edx, 4(%esp) # xcopy = p.x (2ndparam) movl %ecx, 8(%esp) # ycopy = p.y (3rdparam) movl %eax, (%esp) # &c is 1st param call move subl $4, %esp movl -24(%ebp), %eax # c.x in %eax movl -20(%ebp), %edx # c.y in %edx movl %eax, -16(%ebp) # q.x = c.x movl %edx, -12(%ebp) # q.y = c.y
Original C code void make() { point p, q; p.x = 1; p.y = 2; q = move(p, 3, 4); } More like IA32 code void make() { point p, q, c; intxcopy, ycopy; p.x = 1; p.y = 2; xcopy = p.x; ycopy = p.y; move(&c, xcopy, ycopy, 3, 4); q.x = c.x; q.y = c.y; } IA32 code make: pushl %ebp movl %esp, %ebp subl $44, %esp movl $1, -8(%ebp) # p.x = 1 movl $2, -4(%ebp) # p.y = 2 leal -24(%ebp), %eax # &c in %eax movl $4, 16(%esp) # dy is 5thparam (3rd in C) movl $3, 12(%esp) # dx is 4thparam (2nd in C) movl -8(%ebp), %edx movl -4(%ebp), %ecx movl %edx, 4(%esp) # xcopy = p.x (2ndparam) movl %ecx, 8(%esp) # ycopy = p.y (3rdparam) movl %eax, (%esp) # &c is 1st param call move subl $4, %esp movl -24(%ebp), %eax # c.x in %eax movl -20(%ebp), %edx # c.y in %edx movl %eax, -16(%ebp) # q.x = c.x movl %edx, -12(%ebp) # q.y = c.y
More like IA32 code void make() { point p, q, c; intxcopy, ycopy; p.x = 1; p.y = 2; xcopy = p.x; ycopy = p.y; move(&c, xcopy, ycopy, 3, 4); q.x = c.x; q.y = c.y; } make: pushl %ebp movl %esp, %ebp subl $44, %esp movl $1, -8(%ebp) # p.x = 1 movl $2, -4(%ebp) # p.y = 2 leal -24(%ebp), %eax # &c in %eax movl $4, 16(%esp) # dy is 5thparam (3rd in C) movl $3, 12(%esp) # dx is 4thparam (2nd in C) movl -8(%ebp), %edx movl -4(%ebp), %ecx movl %edx, 4(%esp) # xcopy = p.x (2ndparam) movl %ecx, 8(%esp) # ycopy = p.y (3rdparam) movl %eax, (%esp) # &c is 1st param call move subl $4, %esp movl -24(%ebp), %eax # c.x in %eax movl -20(%ebp), %edx # c.y in %edx movl %eax, -16(%ebp) # q.x = c.x movl %edx, -12(%ebp) # q.y = c.y
Original C code point move(point p, int dx, intdy) { p.x += dx; p.y += dy; return p; } move: pushl %ebp movl %esp, %ebp movl 8(%ebp), %ecx # &r in %ecx movl 12(%ebp), %eax # --- addl 20(%ebp), %eax # c.x += dx movl %eax, 12(%ebp) # --- movl 16(%ebp), %eax # --- addl 24(%ebp), %eax # c.y += dy movl %eax, 16(%ebp) # --- movl 12(%ebp), %eax # c.x in %eax movl 16(%ebp), %edx # c.y in %edx movl %eax, (%ecx) # r->x = c.x movl %edx, 4(%ecx) # r->y = c.y movl %ecx, %eax # return r More like IA32 code point *move(point &c, int x, int y, int dx, intdy) { x += dx; y += dy; c -> x = x; c -> y = y; return c;
Original C code void make() { point p, q; p.x = 1; p.y = 2; q = move(p, 3, 4); } point move(point p, int dx, intdy) { p.x += dx; p.y += dy; return p; } More like IA32 code void make() { point p, q, c; p.x = 1; p.y = 2; xcopy = p.x; ycopy = p.y; move(&c, xcopy, ycopy, 3, 4); q.x = c.x; q.y = c.y; } point *move(point &c, int x, int y, int dx, intdy) { x += dx; y += dy; c -> x = x; c -> y = y; return c;
Same program, Using pointers typedefstruct p { int x, y; } point; // same code, except p is modified void make() { point p; p.x = 1; p.y = 2; move(&p, 3, 4); } void move(point *ptr, int dx, intdy) { ptr -> x += dx; ptr -> y += dy; }
Original C code void make() { point p; p.x = 1; p.y = 2; move(&p, 3, 4); } IA32 code make: pushl %ebp movl %esp, %ebp subl $28, %esp movl $1, -8(%ebp) # p.x = 1 movl $2, -4(%ebp) # p.y = 2 movl $4, 8(%esp) # 4 is 3rdparam movl $3, 4(%esp) # 3 is 2ndparam leal -8(%ebp), %eax # &p is 1stparam movl %eax, (%esp) call move leave ret They’re the same!!
Original C code void move(point * ptr, int dx, intdy) { ptr -> x += dx; ptr ->y += dy; } move: pushl %ebp movl %esp, %ebp movl 8(%ebp), %eax # ptr in %eax movl (%eax), %eax # ptr -> x in %eax movl %eax, %edx addl 12(%ebp), %edx # ptr -> x += dx movl 8(%ebp), %eax movl %edx, (%eax) movl 8(%ebp), %eax movl 4(%eax), %eax # ptr-> y in %eax movl %eax, %edx addl 16(%ebp), %edx # ptr -> y += dy movl 8(%ebp), %eax movl %edx, 4(%eax) They’re the same!
Without explicit pointers void make() { point p, q, c; p.x = 1; p.y = 2; xcopy = p.x; ycopy = p.y; move(&c, xcopy, ycopy, 3, 4); q.x = c.x; q.y = c.y; } point *move(point &c, int x, int y, int dx, intdy) { x += dx; y += dy; c -> x = x; c -> y = y; return c; How many copies of data??
Without explicit pointers void make() { point p, q, c; p.x = 1; p.y = 2; xcopy = p.x; ycopy = p.y; move(&c, xcopy, ycopy, 3, 4); q.x = c.x; q.y = c.y; } point *move(point &c, int x, int y, int dx, intdy) { x += dx; y += dy; c -> x = x; c -> y = y; return c; How many copies of data?? --- 2! Only 16 bytes in this example, but with more complex structures, …
With pointers – Only the pointer is copied (4 bytes) With a more complex structure, still only 4 bytes typedefstruct p { int x, y; } point; // same code, except p is modified void make() { point p; p.x = 1; p.y = 2; move(&p, 3, 4); } void move(point *ptr, int dx, intdy) { ptr -> x += dx; ptr -> y += dy; }