C/C++函数调用类型&汇编区别与联系

汇编语言执行call与ret的过程

  没有参数的情况:当执行段内转移时,不将cs压入栈,只压入ip;当执行段间转移时,先将cs压栈,再将ip压栈。返回时先将ip弹出,再根据有无压入cs弹出cs。
  有参数的情况:先将cs、ip依次压入栈中,然后将参数从右向左依次压栈,再push bp,mov bp, sp。当返回时,pop bp, pop ip, pop cs;然后让栈顶指针sp+参数大小,即ret num。

给个考试题及答案:


函数调用类型比较

先写一个测试程序,该程序使用编译器为DevC++:

#include<stdio.h>

int __cdecl fun_cdecl(int a, int b){
	int c = a + b;
	return c;
} 

int __stdcall fun_stdcall(int a, int b){
	int c = a + b;
	return c;
} 

int __fastcall fun_fastcall(int a, int b){
	int c = a + b;
	return c;
} 

int main(){
	printf("here");
	__asm__("nop");
	fun_cdecl(1, 2);
	__asm__("nop");
	fun_stdcall(1, 2);
	__asm__("nop");
	fun_fastcall(1, 2);
	
	__asm__("nop");
	
	return 0;
} 

其中printf(“here”);的作用在于快速找到下面三个函数的位置。使用x64dbg进行动态调试,右键搜索字符串,点击here跳转到三个函数位置,如下:

由于不同软件对于反汇编的精细程度不同,因此,同时使用了OllyDbg进行观察,如下:

下面来分析每种调用类型的区别。

指令leave等价于
mov esp, ebp
由于起始部分有:
push ebp
mov ebp, esp
的操作,因此leave完成了对局部变量的回收工作

__cdecl调用

  __cdecl 是C Declaration的缩写(declaration,声明),表示C语言默认的函数调用方法:所有参数从右到左依次入栈,这些参数由调用者清除,称为手动清栈。被调用函数不会要求调用者传递多少参数,调用者传递过多或者过少的参数,甚至完全不同的参数都不会产生编译阶段的错误。


  观察到,对于__cdecl调用方式,使用ret形式,要求调用者自行回收参数;且x64Dbg认为进行了压栈,而OD认为并没用执行参数压栈操作。

__stdcall调用

  被这个关键字修饰的函数,其参数都是从右向左通过堆栈传递的, 函数调用参数在返回前要由被调用者清理堆栈。


  观察到,对于__stdcall调用方式,使用retn 0x8形式,由被调用者回收参数;且x64Dbg认为进行了压栈,而OD认为并没用执行参数压栈操作。

__fastcall调用

  规定将前两个参数由寄存器ecx和edx来传递,其余参数从右到左通过堆栈传递,函数调用参数在返回前要由被调用者清理堆栈,这与__stdcall相同。


  观察到,对于__fastcall调用方式,使用retn形式,这与编译器的优化方式有关;由被调用者回收参数;且x64Dbg认为进行了压栈,而OD认为并没用执行参数压栈操作;前两个参数由ecx和edx传递,符合设计。

总结

  三种不同的调用方式在各自目录下已经进行了阐述,不再赘述。由于编译环境和反汇编环境的不同,观察到反汇编结果也有很大区别;就ret而言,OD反汇编更加精细,而就参数压栈而言,x64Dbg反汇编更加精细,可见二者各有所长。

另外:x64Dbg可以调试64位程序;而OD虽然既可以在32位系统下运行,也可以在64位系统下运行,但是却只能对32位程序进行调试,因此,两者结合使用效果更佳。期待OD更新。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

D-A-X

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值