题目: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寄存器,后再返回。