This article will analyze the running process of C program on IA-32 system pc through compiler generated assembly code.
Experimental environment: GCC 4.8.2
Memory structure of C language program
C code is as follows
int g(int x){ return x + 1;}int f(int x){ return g(x);}int main(void){ return f(2) + 3;}
Compile gcc -S -O0 -o main.s main.c -m32
The assembly file using the Compile command, as follows
g: pushl %ebp movl %esp, %ebp movl 8(%ebp), %eax addl $1, %eax popl %ebp retf: pushl %ebp movl %esp, %ebp subl $4, %esp movl 8(%ebp), %eax movl %eax, (%esp) call g leavemain: pushl %ebp movl %esp, %ebp subl $4, %esp movl $2, (%esp) call f addl $3, %eax leave
The entry point is in main and is parsed by main
- PUSHL%EBP
- Subl $4,%esp
- Movl%ebp, (%ESP)
- This is the first operation after entering the main function, saving the original EBP, that is, the stack site before main begins execution
- MOVL%esp,%EBP
- The value of ESP enters EBP, where the bottom is set to the top of the stack before main, that is, starting here, the new stack behind EBP is caused by the operation in the main function, each time the change in EBP means the current function changes.
- Subl $4,%esp
- MOVL, (%ESP)
- The above two sentences are actually executed by PUSHL,%ESP, which will immediately count 2 into the stack,
- After the execution of this sentence, use GDB to view the value of the EIP as 0x8048418<main+13>, that is, the next line call F
- Call F
- PUSHL%eip
- JMP F
- Call the F function, the above two sentences into the stack immediately number 2 is the function f parameter, and the EIP point to the entrance address of F
- Addl,%eax
- EAX stores the result returned by the function f call, and this statement adds the immediate number 3 to the EAX.
- Leave
- MOVL%EBP,%esp
- POPL%EBP
- These two sentences restore EBP to the scene before calling Main, where the main function call ends
- Ret
- POPL%eip
- The EIP refers to the callback with the address before main, exit function main
The first function call after entering main F (x)
- PUSHL%EBP
- MOVL%esp,%EBP
- The function here is the same as in main, does not repeat the description
- Subl $4,%esp
- Leave the stack space for the parameter
- MOVL 8 (%EBP),%eax
- The stack address is growing downward, where ebp+8 is getting the address that is pressed into the EIP and parameters, which is the argument that is stored in the EAX
- Movl%eax, (%ESP)
- EAX into the stack, that is, the parameter into the stack, C code in the function g parameter is the function f receive parameters, so directly call the G function
- Call G
- Leave
- The above two lines are consistent with main and no longer repeat
- Ret
- Consistent with the main function
Last function call G (x)
- PUSHL%EBP
- MOVL%esp,%EBP
- Consistent with the previous description, do not repeat
- MOVL 8 (%EBP),%eax
- Still consistent with the function in F
- Addl $,%eax
- function g function, that is, on the parameter +1
- POPL%EBP
- MOVL (%ESP),%EBP
- Addl $4,%esp
- Restore the stack before calling G
- Ret
- POPL%eip
- The EIP is referred back to the address before the function g called, that is, return to function f
C Language Program in the operation of the IA-32 machine, the most important instructions are Push/pop,call/ret, wherein PUSH/POP implements the basic operation of the stack, call/ret maintenance of the function of the call stack, to ensure that the function call process continuous
Using DDD to capture the changes of the EIP before and after the call, it is clear that the non-linear change of EIP at call
Finally, look at the effect that compiler optimizations can do to gcc -S -O3 -o test.s test.c -m32
compile the above code, and get the assembly as follows
g: movl 4(%esp), %eax addl $1, %eax retf: movl 4(%esp), %eax addl $1, %eax retmain: movl $6, %eax ret
You can see that the compiler directly calculates the result of the main function as an immediate number returned. is still very powerful. F and G This simple function also does not reset the bottom of the stack, but the direct use of the variable address addressing, improve the efficiency of operation
Cloud class Assignments
Wu, original works reproduced please indicate the source, "Linux kernel analysis" MOOC course
Analysis of simple C program running process on IA-32 CPU