汇编指令执行过程分析
一、编写C程序,并编译
// main.c
int g(int x)
{
return x + 1;
}
int f(int x)
{
return g(x);
}
int main(void)
{
return f(1) + 1;
}
$ gcc –S –o main.s main.c -m32
编译后

删除以“.”开头的辅助信息后

g:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax
addl $1, %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
二、下面分析过程
1.首先执行main函数,
pushl %ebp保存调用函数的基址(ebp中)到栈中,压栈操作此时esp自动下移一个地址空间(4个字节)
movl %esp, %ebp将esp的内容放到ebp中,设置ebp为当前被调用函数的基址指针,即当前栈顶
subl $4, %espesp下移一个地址空间(4个字节),为当前函数分配1个栈空间(4个字节)用于存储局部变量
movl $1, (%esp)将1放到esp当前指向的位置
call f=pushl %eip(*) movl f %eip(*)将此时eip中的值(下一条指令addl $1, %eax)压栈,然后将f函数的地址放到eip中,这样程序转而执行f函数。
2.执行f函数
pushl %ebp保存调用函数的基址(ebp中)到栈中,压栈操作此时esp自动下移一个地址空间(4个字节)
movl %esp, %ebp将esp的内容放到ebp中,设置ebp为当前被调用函数的基址指针,即当前栈顶
subl $4, %espesp下移一个地址空间(4个字节),为当前函数分配1个栈空间(4个字节)用于存储局部变量
movl 8(%ebp), %eaxebp中的地址上移2个(8个字节)地址空间的内容放到eax中,也就是将数字1放到eax中
movl %eax, (%esp)将eax中的内容放到esp当前指向的位置
call g =pushl %eip(*) movl g %eip(*)将此时eip中的值(下一条指令leave)压栈,然后将g函数的地址放到eip中,这样程序转而执行g函数。
3.执行g函数
pushl %ebp 保存调用函数的基址(ebp中)到栈中,压栈操作此时esp自动下移一个地址空间(4个字节)
movl %esp, %ebp将esp的内容放到ebp中,设置ebp为当前被调用函数的基址指针,即当前栈顶
movl 8(%ebp), %eax将ebp上移2个地址空间的内容放到eax中,就是数字1
addl $1, %eax将1与eax中的数相加,也就是2放到eax中
popl %ebp 恢复ebp为调用函数基址
ret =popl %eip(*)就是f函数中的leave
4.返回执行f函数
leave=movl %ebp,%esp popl %ebp将ebp中的那内容放到esp,将回复ebp为调用函数基址
ret=popl %eip(*)就是main函数中的addl $1, %eax
5.返回执行main函数
addl $1, %eax将1与eax中的内容相加,也就是1+2=3,将3放到eax中
leave=movl %ebp,%esp popl %ebp将ebp中的那内容放到esp,将回复ebp为调用函数基址
ret返回main函数之前的堆栈

浙公网安备 33010602011771号