c,c++函数调用的汇编过程
开始温习C,C++,以前都是看effective c++之类的书籍,对c++原理不甚了解,为了知其所以然,
今天仔细研究了一下一个简单的函数的汇编过程。请各位大侠多指教。
?
?
/* 如下代码使用GUN GCC编译,反汇编如下 */
int main(int argc,char **args)
{
? ? int a=20;
? ? int b=30;
? ? int c=0;
? ? c=a+b;
? ? return 0;
}
?
?
004016DDpush ? %ebp ? /*将栈底指针入操作栈,保存main函数的上级调用函数的栈基地址,此处为操作系统调用基地址*/
004016DEmov ? ?%esp,%ebp /* 保存esp指针值,放入到ebp栈底指针中,设置main函数的基地址,以便函数return后返回上级调用基地址 */
004016E0and ? ?$0xfffffff0,%esp ?/* 使栈的地址以16字节对齐 ?*/
004016E3sub ? ?$0x10,%esp ? ? ? ?/* 由于i386架构的栈是向下扩展的,因此,采用esp地址减去16字节,开辟局部变量空间 */
004016E6call ? 0x401d44 <__main> /* 调用main函数地址0x401d44 */
004016EBmovl ? $0x14,0xc(%esp) ? /*将变量a=0x14即20这个局部变量push到栈中,其内存地址为0xc */
004016F3movl ? $0x1e,0x8(%esp) ? /* 将变量b=0x1e即30这个局部变量push到栈中,内存地址为0x8 */
004016FBmovl ? $0x0,0x4(%esp) ? ?/* 将变量c=0即0x0push到栈中,内存地址为0x4 */
00401703mov ? ?0x8(%esp),%eax ? ?/* 将内存地址为0x8的值即30放入eax寄存器 */
00401707mov ? ?0xc(%esp),%edx ? ?/* 将内存地址为0xc即20放入edx寄存器 */
0040170Badd ? ?%edx,%eax ? ? ? ? /* 调用add指令将edx,eax值相加,并将结果存入eax寄存器*/
0040170Dmov ? ?%eax,0x4(%esp) ? ?/* 将eax寄存器的值放入栈地址为0x4即变量c中,此时0x4地址处的职位50 */
00401711mov ? ?$0x0,%eax ? ? ? ? /* 设置函数返回值为0,linux/Unix下均采用eax寄存器作为函数返回值的寄存器*/
00401716leave ? ? ? ? ? ? ? ? ? ?/* 该指令将ebp值赋给esp,pop先前栈内的上级函数栈的基地址给ebp,恢复原栈基址 */
00401717ret ? ? ? ? ? ? ? ? ? ? ?/* main函数返回,回到上级调用 */