題目:C語言生成彙編代碼的執行流程
1、 C語言代碼如下:
int g(int x)
{
return x + 10;
}
int f(int x)
{
return g(x);
}
int main(void)
{
return f(1) + 1;
}
2、 使用命令:gcc –S –o main.s main.c -m32(說明:生成是32位的彙編指令,系統是32位linux系統CentOS5.5,其他不同位系統生成代碼略有不同) 生成彙編代碼後如下:
以“.”開頭的代碼是註釋代碼
.file "main.c"
.text
.globl g
.type g, @function
g:
.LFB0:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset8
.cfi_offset5, -8
movl %esp, %ebp
.cfi_def_cfa_register5
movl 8(%ebp), %eax
addl $10, %eax
popl %ebp
.cfi_restore5
.cfi_def_cfa4, 4
ret
.cfi_endproc
.LFE0:
.size g, .-g
.globl f
.type f, @function
f:
.LFB1:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset8
.cfi_offset5, -8
movl %esp, %ebp
.cfi_def_cfa_register5
subl $4, %esp
movl 8(%ebp), %eax
movl %eax, (%esp)
call g
leave
.cfi_restore5
.cfi_def_cfa4, 4
ret
.cfi_endproc
.LFE1:
.size f, .-f
.globl main
.type main, @function
main:
.LFB2:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset8
.cfi_offset5, -8
movl %esp, %ebp
.cfi_def_cfa_register5
subl $4, %esp
movl $1, (%esp)
call f
addl $1, %eax
leave
.cfi_restore5
.cfi_def_cfa4, 4
ret
.cfi_endproc
.LFE2:
.size main, .-main
.ident "GCC: (Ubuntu 4.8.2-19ubuntu1)4.8.2"
.section .note.GNU-stack,"",@progbits
3、 執行流程
簡化後代碼:
g:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax
addl $10, %eax
popl %ebp
ret
f:
pushl %ebp
movl %esp, %ebp
subl $4, %esp
movl 8(%ebp), %eax
movl %eax, (%esp)
call g
leave
ret
main:
pushl %ebp
movl %esp, %ebp
subl $4, %esp
movl $1, (%esp)
call f
addl $1, %eax
leave
ret
執行過程:
首先從main函數開始執行,將ebp寄存器地址入棧並將esp指針指向ebp,esp地址減去4個字節,變成紅色指向的內容,然後將1賦值給esp指針。
然後是系統保存當前的環境變量,調用f函數。此工作過程與main函數調用是一樣的,不同是將8賦值了給eax寄存器,再eax寄存器的值賦值給esp指針。
然後是系統保存當前的環境變量,調用g函數。此工作過程與f函數調用是一樣的,將數值10與eax寄存器的值相加,ebp寄存器出棧,返回f調用函數處的下一條指令。同樣的,ebp寄存器出棧,返回main調用函數處的下一條指令,eax寄存器加1後並將值賦值eax寄存器,後再返回。