Sjtubear original works reproduced please indicate the source/"Linux kernel Analysis" MOOC course http://mooc.study.163.com/course/USTC-1000029000
1. Compilation
In the initial stage of the course of the Linux kernel, the first thing you need to master is the assembly and the operation of the assembler for the stack.
Now let's analyze how a simple C program is expressed by the assembler program!
2. Get Assembly code
First, we write a simple C program, named EXP1.C:
1#include <stdio.h>2 3 intGintx)4 {5 returnx+3;6 }7 8 intf (x)9 {Ten returng (x); One } A - intMain () - { the returnF8)+1; -}
The program is very simple and we compile it into a assembler by compiling the instructions at this point:
1 gcc–s–o main.s main.c-m32
So we get the assembly code for this simple C program:
1. file"exp1.c"2 . Text3 . Globl g4 . Type G, @function5 g:6.LFB0:7 . Cfi_startproc8 PUSHL%EBP9. cfi_def_cfa_offset8Ten. cfi_offset5, -8 One movl%esp,%EBP A. cfi_def_cfa_register5 -Movl8(%EBP),%eax -Addl $3,%eax the popl%EBP -. CFI_DEF_CFA4,4 -. cfi_restore5 - ret + . Cfi_endproc -.LFE0: + . Size g,.-G A . globl F at . Type F, @function - F: -.LFB1: - . Cfi_startproc - PUSHL%EBP -. cfi_def_cfa_offset8 in. cfi_offset5, -8 - movl%esp,%EBP to. cfi_def_cfa_register5 +SUBL $4,%esp -Movl8(%EBP),%eax the movl%eax, (%ESP) * Pagerg $ LeavePanax Notoginseng. cfi_restore5 -. CFI_DEF_CFA4,4 the ret + . Cfi_endproc A.LFE1: the . Size F,.-F + . Globl Main - . Type Main, @function $ Main: $.LFB2: - . Cfi_startproc - PUSHL%EBP the. cfi_def_cfa_offset8 -. cfi_offset5, -8Wuyi movl%esp,%EBP the. cfi_def_cfa_register5 -SUBL $4,%esp WuMOVL $8, (%ESP) - PagerF AboutAddl $1,%eax $ Leave -. cfi_restore5 -. CFI_DEF_CFA4,4 - ret A . Cfi_endproc +.LFE2: the . Size main,.-main -. ident"GCC: (Ubuntu/linaro 4.6.3-1ubuntu5) 4.6.3" $. section. Note. Gnu-stack,"", @progbits
3. Assembly Code Analysis
Compiled code, a lot of auxiliary information, in order to better see the trunk, we cut:
1 g:2 PUSHL%EBP//Save the site and deposit the base register of the parent function in the current stack3 movl%esp,%EBP//building the current function stack4Movl8(%EBP),%eax//Get parameters from the parent function stack, deposit into the AX register5Addl $3,%eax//complete +3 operation6 popl%EBP//Restoring the original parent function stack7 ret//pop out the original EIP address, resume execution8 F:9 PUSHL%EBP//Save the site and deposit the base register of the parent function in the current stackTen movl%esp,%EBP//building the current function stack OneSUBL $4,%ESP//stack top plus one, to store variables passed to the G function AMovl8(%EBP),%eax//Get Parameters - movl%eax, (%ESP)//passing parameters to the variable position - Pagerg//Call G the Leave//clear local variable space - ret//Return - Main: - PUSHL%EBP + movl%esp,%EBP -SUBL $4,%ESP//vacated local variable space +MOVL $8, (%ESP)//Assign a value to a variable A Pagerf//Call F atAddl $1,%eax//complete +1 operation - Leave//Clean up local variables - retReturn
We analyze the F function in detail:
1. First enter the command:
At this point, the location to which EBP is currently pointing is deposited on top of the stack, and EBP is redirected to ESP:
2. Stack top plus the value of the variable:
3. Call G
4. After returning from G, the return value is stored in the AX register without action, calling leave, cleaning the variable
5. Finally ret, while the EIP is read back to the original location to continue execution, the return value is passed to the calling function in ax
3. A little bit of personal sentiment:
The invocation of the program is done in such a nested way that each function has its own stack to store the current variable and the environment value, and to restore the environment by placing the EBP of the parent function on the bottom of the stack.
At the same time, the EIP is deposited to the top of the parent stack to resume execution at the original node.
In this way, it can be regularly nested down.
If you use a recursive function, which is the process of a code stack, knowing that the topmost stack is returned, the function will retract all stacks like dominoes.
This is one of the reasons why recursive functions occupy more space. If the mechanism is not well exited, there is a possibility of memory overflow.
A brief analysis of the running mode of C program Assembly