java函数调用约定_调用约定(Calling Conventions) 函数名修饰(Name Mangling) 二进制分析工具...

一、申明调用约定

Windows的调用约定可以是__cdecl、__stdcall、__fastcall,如下示例申明调用约定:

int __cdeclmyFunc();

Linux默认调用约定是cdecl,如下示例申明调用约定:

int __attribute__((cdecl)) myFunc();

int __attribute__((stdcall)) myFunc();

二、使用调用约定

大多数时候我们不需要关注函数的调用约定,但如果需要跨语言的编程(C++调用C库需要使用extern "C"说明),则需要关注。

Microsoft的VC默认的是__cdecl,而Windows API则是__stdcall,如果用VC开发DLL给其他语言用,则应该指定__stdcall方式。堆栈由谁清除这个很重要,写汇编函数给C调用,一定要小心堆栈的清除工作,如果是__cdecl方式调用,汇编函数本身不需要关心保存参数的堆栈清除,如果是__stdcall方式调用,一定要在函数退出(ret)前恢复堆栈。

1.__cdecl

按从右至左的顺序压参数入栈,由调用者把参数弹出栈。切记:对于传送参数的内存栈是由调用者来维护的,返回值在EAX中。因此对于像printf这样可变参数的函数必须用这种约定。编译器在编译的时候对这种调用规则的函数生成修饰名的时候,在输出函数名前加上一个下划线前缀,格式为_function。

2.__stdcall

按从右至左的顺序压参数入栈,由被调用者把参数弹出栈。__stdcall通常用于Win32 API中,切记:函数自己在退出时清空堆栈,返回值在EAX中。__stdcall调用约定在输出函数名前加上一个下划线前缀,后面加上一个“@”符号和其参数的字节数,格式为_function@number。如函数int func(int a, double b)的修饰名是_func@12。

3.__fastcall

__fastcall调用的主要特点就是快,因为它是通过寄存器来传送参数的(实际上它用ECX和EDX传送前两个DWORD或更小的参数,剩下的参数仍自右向左压栈传送,被调用的函数在返回前清理传送参数的内存栈)。__fastcall调用约定在输出函数名前加上一个“@”符号,后面也是一个“@”符号和其参数的字节数,格式为@function@number。这个和__stdcall很象,唯一差别就是头两个参数通过寄存器传送。注意通过寄存器传送的两个参数是从左向右的,即第1个参数进ECX,第2个进EDX,其他参数是从右向左的入栈,返回仍然通过EAX。

三、C++函数名修饰(Decorated Names,Name Mangling)

1.以"?"标识函数开始,后跟函数名。

2.函数名后面标识调用约定,然后跟参数列表。

__cdecl,@@YA

__stdcall,@@YG

__fastcall,@@YI

3.参数类型代号编码。

X--void

D--char

E--unsigned char

F--short

H--int

I--unsigned int

J--long

K--unsigned long

M--float

N--double

4.参数表第一项为该函数的返回值类型。

5.参数表后以"@Z"标识整个函数名结束,如果该函数无参数,则以"Z"标识结束。

6.比如:“?a@@YAHD@Z”原函数为“int __cdecl a(char)”。

9115893cc972e7f67958846515b55f67.png

四、二进制分析工具

Name Mangling解析工具,界面如上截图:

Name Mangling解析工具,viusal studio的命令行工具undname.exe;

可执行文件(exe、dll、lib)解析工具,viusal studio的命令行工具dumpbin.exe;

Linux下常用工具:

objdump -d elf-file,反汇编.text段;

objdump -S elf-file,同时显示源码和反汇编;

objdump -x elf-file,查看elf文件分段信息;

objdump -h elf-file,查看elf文件section信息;

objdump -a elf-file,显示归档信息;

nm elf-file,显示符号表信息,用于解决链接错误;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值