首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >GCC忽视了cdecl?

GCC忽视了cdecl?
EN

Stack Overflow用户
提问于 2015-12-20 10:22:35
回答 2查看 5.7K关注 0票数 4

我在Linux x86上使用gcc。我的程序将指向C函数的指针导出到LLVM JIT函数。呼叫会议是cdecl。它在MingW上运行良好。但是,奇怪的事情发生在linux x86平台上。导出的C函数的分解如下所示:

代码语言:javascript
复制
push   ebp
mov    ebp,esp
push   ebx
sub    esp,0x34
mov    eax,0xfffffffc
mov    eax,DWORD PTR gs:[eax]
mov    eax,DWORD PTR [eax+0x1c]
mov    eax,DWORD PTR [eax]
mov    eax,DWORD PTR [eax+0x28]
mov    edx,DWORD PTR [ebp+0xc]
shl    edx,0x4
add    eax,edx
mov    DWORD PTR [ebp-0xc],eax
mov    edx,DWORD PTR ds:0x8e49940
mov    ebx,DWORD PTR [ebp+0x8]
lea    eax,[ebp-0x20]
mov    ecx,DWORD PTR [ebp-0xc]
mov    DWORD PTR [esp+0xc],ecx
mov    ecx,DWORD PTR [ebp+0x10]
mov    DWORD PTR [esp+0x8],ecx
mov    DWORD PTR [esp+0x4],edx
mov    DWORD PTR [esp],eax
call   0x8090f6f <SoCreateArray(DVM_VirtualMachine_tag*, int, DVM_TypeSpecifier_tag*)>
sub    esp,0x4
mov    eax,DWORD PTR [ebp-0x20]
mov    edx,DWORD PTR [ebp-0x1c]
mov    DWORD PTR [ebx],eax
mov    DWORD PTR [ebx+0x4],edx
mov    eax,DWORD PTR [ebp+0x8]
mov    ebx,DWORD PTR [ebp-0x4]
leave
ret    0x4

C源代码在这里:

代码语言:javascript
复制
DVM_ObjectRef SoNewArray(BINT ty,BINT dim)
{
    DVM_TypeSpecifier *type
        = &curthread->current_executable->executable->type_specifier[ty];
    DVM_ObjectRef barray;
    barray = SoCreateArray(curdvm, dim, type);
    return barray;
}

注意,反汇编代码的最终指令是“ret0x4”,这意味着它自己清理堆栈的函数,而不是cdecl函数!更重要的是,即使我这样声明C函数:

attribute((cdecl));DVM_ObjectRef SoNewArray(BINT,BINT SoNewArray)

结果是一样的。也许GCC优化了我的代码,并自动使用stdcall,而忽略了调用约定?

我的GCC指挥官是

gcc -Wall -fexceptions --Wall errors -g

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-03-07 04:09:31

https://www.zhihu.com/question/38726507

这是一个来自“智湖”的回答,一个中文的“堆叠溢出”。感谢RednaxelaFX @志虎。我发现这个问题的真正原因是函数返回的是一个结构,而不是一个基本类型。请参见函数声明:

代码语言:javascript
复制
DVM_ObjectRef SoNewArray(BINT ty,BINT dim)

DVM_ObjectRef是一种结构。当x86 gcc处理像上面这样的函数时,它实际上生成:

代码语言:javascript
复制
DVM_ObjectRef SoNewArray(DVM_ObjectRef * ret,BINT ty,BINT dim)

请参阅有关x86调用约定的详细信息:

http://www.angelcode.com/dev/callconv/callconv.html

票数 1
EN

Stack Overflow用户

发布于 2017-02-25 13:20:51

我的gcc 5.4.0在64位linux上需要__attribute__((__cdecl__))

代码语言:javascript
复制
#ifdef __GNUC__
#define _cdecl __attribute__((__cdecl__))
#endif

//sometime later
int _cdecl AddItemVar(void *AContext,void *AFun,long ACfg1,...);

代码最初来自__BORLANDC__,但也使用__WATCOMC__和__MSVC__进行编译。编译会产生以下警告:

././LIB/DevOS.C/DevOS.h:242:64:警告:‘cdecl’属性忽略-Wattributes

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34379974

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档