C 显示每个函数';s使用objdump或类似工具调用约定

C 显示每个函数';s使用objdump或类似工具调用约定,c,calling-convention,objdump,C,Calling Convention,Objdump,我有一个由GCC从C源文件生成的可执行文件(或.o)如何使用objdump或类似工具显示文件中包含的每个函数的调用约定? 理由 当查看反汇编时,我似乎有一个函数a(),它通过在堆栈上按y和x调用另一个函数B(x,y),但是B(x,y)在寄存器中查找其参数 我在B(x,y)的C源代码上没有看到任何\uuu cdecl、\uu stdcall或类似的注释,也没有看到任何C/C++不兼容的奇怪之处,所以我想从实际的.o或可执行文件中查询它使用的约定,而不是随机猜测 一位同事发现了问题:在(相当长的)文

我有一个由GCC从C源文件生成的可执行文件(或
.o
如何使用
objdump
或类似工具显示文件中包含的每个函数的调用约定?

理由 当查看反汇编时,我似乎有一个函数
a()
,它通过在堆栈上按
y
x
调用另一个函数
B(x,y)
,但是
B(x,y)
在寄存器中查找其参数

我在
B(x,y)
的C源代码上没有看到任何
\uuu cdecl
\uu stdcall
或类似的注释,也没有看到任何C/C++不兼容的奇怪之处,所以我想从实际的
.o
或可执行文件中查询它使用的约定,而不是随机猜测

一位同事发现了问题:在(相当长的)文件中的某个地方 有一个
#pragma
改变了GCC优化级别(从
O2
O0
我想)。因此,
B
定义为
O2
激活,而
A
定义为激活 当
O0
处于活动状态时。这应该不是问题,但似乎GCC 版本阻塞了它,在
A
中它调用
B
,就好像
B
也是
O0
一样,但是
O0
O2
具有不同的调用约定

…有趣的,好的观察

我认为信息包含在
.o
中,因为调用 作为一个单独的
.o
中的函数,GCC知道约定并生成 正确的代码

这种推理是错误的。在您的情况下,
B
必须定义为
静态
;从寄存器加载参数的优化不是在具有外部链接的函数中完成的。这就解释了为什么在单独的
.o
中调用函数时,GCC…会生成正确的代码-它只是不执行优化;因此,GCC没有必要从
.o
中包含的一些信息中了解约定,而这些信息并不存在

一位同事发现了问题:在(相当长的)文件中的某个地方 有一个
#pragma
改变了GCC优化级别(从
O2
O0
我想)。因此,
B
定义为
O2
激活,而
A
定义为激活 当
O0
处于活动状态时。这应该不是问题,但似乎GCC 版本阻塞了它,在
A
中它调用
B
,就好像
B
也是
O0
一样,但是
O0
O2
具有不同的调用约定

…有趣的,好的观察

我认为信息包含在
.o
中,因为调用 作为一个单独的
.o
中的函数,GCC知道约定并生成 正确的代码


这种推理是错误的。在您的情况下,
B
必须定义为
静态
;从寄存器加载参数的优化不是在具有外部链接的函数中完成的。这就解释了为什么在单独的
.o
中调用函数时,GCC…会生成正确的代码-它只是不执行优化;因此,GCC没有必要从
.o
-中包含的一些信息中了解约定,这些信息不存在。

反汇编并查看函数调用如何工作?@KerrekSB好吧,这就是我所做的,但读取100行汇编代码是困难的,它只告诉我函数似乎在做什么,但不是调用约定的名称,所以我不得不猜测反向工程是这样的。很可能您会从操作系统/硬件文档中发现调用约定比反向工程objdump输出更快。在网上搜索“调用约定”可能会很有启发性(我感觉这可能是某种linux)。@SamiLaine我不知道这对我有什么帮助。。。在C程序中,函数不一定都使用相同的调用约定,我发现调用方使用的调用约定与被调用方不同,这当然不起作用。我没有添加任何注释来更改默认的调用约定(但这不是我的代码)。结果仍然是在同一个C文件中有两种不同的调用约定。我想知道确切的事实,知道被调用方的有效调用约定是什么,这样我就可以查找导致这种行为的原因(可能是某个属性)。@gnometorule,@SamiLaine:一位同事发现了问题:在(相当长的时间)的某个地方文件中有一个
#pragma
,它改变了GCC的优化级别(我认为从
O2
O0
)。因此,
B
定义为
O2
激活,
A
定义为
O0
激活。这不应该是一个问题,但GCC版本似乎被它阻塞了,在
a
中,它调用
B
就像
B
也是
O0
一样,但是
O0
O2
有不同的调用约定。我认为信息包含在
.o
中,因为当在单独的
.o
中调用函数时,GCC知道约定并生成正确的代码。分解并查看函数调用如何工作?@KerrekSB好吧,这是我所做的,但读取100行汇编代码是困难的,它只告诉我函数似乎在做什么,但没有告诉调用约定的名称,所以我猜是反向工程。很可能你会从操作系统/硬件文档中发现调用约定比反向工程objdump输出更快。在网上搜索“调用约定”可能会很有启发性(我感觉这可能是某种linux)。@SamiLaine我不知道这对我有什么帮助。。。在C-p中