c - Help deciphering simple Assembly Code -
i learning assembly using gdb & eclipse
here simple c code.
int absdiff(int x, int y) { if(x < y) return y-x; else return x-y; } int main(void) { int x = 10; int y = 15; absdiff(x,y); return exit_success; }
here corresponding assembly instructions main()
main: 080483bb: push %ebp #push old frame pointer onto stack 080483bc: mov %esp,%ebp #move frame pointer down, position of stack pointer 080483be: sub $0x18,%esp # ??? 25 int x = 10; 080483c1: movl $0xa,-0x4(%ebp) #move "x(10)" 4 address below frame pointer (why not push?) 26 int y = 15; 080483c8: movl $0xf,-0x8(%ebp) #move "y(15)" 8 address below frame pointer (why not push?) 28 absdiff(x,y); 080483cf: mov -0x8(%ebp),%eax # -0x8(%ebp) == 15 = y, , move %eax 080483d2: mov %eax,0x4(%esp) # point on, confused 080483d6: mov -0x4(%ebp),%eax 080483d9: mov %eax,(%esp) 080483dc: call 0x8048394 <absdiff> 31 return exit_success; 080483e1: mov $0x0,%eax 32 }
basically, asking me make sense of assembly code, , why doing things in particular order. point stuck, shown in assembly comments. !
first bears saying assembly in at&t syntax version of x86_32, , order of arguments operations reversed intel syntax (used masm, yasm, , many other assemblers , debuggers).
080483bb: push %ebp #push old frame pointer onto stack 080483bc: mov %esp,%ebp #move frame pointer down, position of stack pointer 080483be: sub $0x18,%esp # ???
this enters stack frame. frame area of memory between stack pointer (esp) , base pointer (ebp). area intended used local variables have live on stack. note: stack frames don't have implemented in way, , gcc has optimization switch -fomit-frame-pointer
away except when alloca
or variable sized arrays used, because implemented changing stack pointer arbitrary values. not using ebp frame pointer allows used general purpose register (more general purpose registers good).
using base pointer makes several things simpler calculate compilers , debuggers, since variables located relative base not change while in function, can index them relative stack pointer , same results, though stack pointer tend change around same location may require different index @ different times.
in code 0x18 (or 24) bytes being reserved on stack local use.
this code far called function prologue (not confused programming language "prolog").
25 int x = 10; 080483c1: movl $0xa,-0x4(%ebp) #move "x(10)" 4 address below frame pointer (why not push?)
this line moves constant 10 (0xa) location within current stack frame relative base pointer. because base pointer below top of stack , since stack grows downward in ram index negative rather positive. if indexed relative stack pointer different index used, positive.
you correct value have been pushed rather copied this. suspect done way because have not compiled optimizations turned on. default gcc (which assume using based on use of gdb) not optimize much, , code default "copy constant location in stack frame" code. may not case, 1 possible explanation.
26 int y = 15; 080483c8: movl $0xf,-0x8(%ebp) #move "y(15)" 8 address below frame pointer (why not push?)
similar previous line of code. these 2 lines of code put 10 , 15 local variables. on stack (rather in registers) because unoptimized code.
28 absdiff(x,y);
gdb printing meant source code line being executed, not function being executed (yet).
080483cf: mov -0x8(%ebp),%eax # -0x8(%ebp) == 15 = y, , move %eax
in preparation calling function values being passed arguments need retrieved storage locations (even though placed @ locations , values known because of no optimization thing)
080483d2: mov %eax,0x4(%esp) # point on, confused
this second part of move stack of 1 of local variables' value can use argument function. can't (usually) move 1 memory address on x86, have move through register (eax
in case).
080483d6: mov -0x4(%ebp),%eax 080483d9: mov %eax,(%esp)
these 2 lines same thing except other variable. note since variable being moved top of stack no offset being used in second instruction.
080483dc: call 0x8048394 <absdiff>
this pushed return address top of stack , jumps address of absdiff
.
you didn't include code absdiff
, did not step through that.
31 return exit_success; 080483e1: mov $0x0,%eax
c programs return 0 upon success, exit_success defined 0 someone. integer return values put in eax
, , code called main
function use value argument when calling exit
function.
32 }
this end. reason gdb stopped here there things happen clean up. in c++ common see destructor local class instances being called here, in c see function epilogue. compliment function prologue, , consists of returning stack pointer , base pointer values at. done similar math on them, done leave
instruction. there enter
instruction can used prologue, gcc doesn't (i don't know why). if had continued view disassembly here have seen epilogue code , ret
instruction.
something may interested in ability tell gcc produce assembly files. if do:
gcc -s source_file.c
a file named source_file.s
produced assembly code in it.
if do:
gcc -s -o source_file.c
then same thing happen, basic optimizations done. make reading assembly code easier since code not have many odd instructions seem have been done better way (like moving constant values stack, register, location on stack , never using push instruction).
you regular optimization flags gcc are:
-o0 default -- none -o1 few optimizations -o same -o1 -o2 lot of optimizations -o3 bunch more, of may take long time and/or make code lot bigger -os optimize size -- similar -o2, not quite
if trying debug c programs want least optimizations possible since things happen in order written in code , variables won't disappear.
you should have @ gcc man page:
man gcc
Comments
Post a Comment