gcc cdecl调用约定

时间:2011-09-18 14:11:01

标签: gcc disassembly cdecl

测试一个cdecl调用约定,但是这有点混乱: 原始C代码:

int __attribute__((cdecl)) add(int a,int b)
{
        int i;
        i = a+b;
        return i;
}

void __attribute__((cdecl)) print(int i, ...)
{
        int j,a,b;
        a = 2;
        b = 3;
        j = add(a,b);
}
void __attribute__((cdecl)) main(void)
{
        print(2,3);
}

void __attribute__((cdecl)) main(void)
{
        print(2,3);
}
compile code with this:
gcc test3.c -o test3 -g -mrtd
the corresponding asm like that:
(gdb) disassemble print
Dump of assembler code for function print:
   0x080483cb <+0>: push   ebp
   0x080483cc <+1>: mov    ebp,esp
   0x080483ce <+3>: sub    esp,0x18
   0x080483d1 <+6>: mov    DWORD PTR [ebp-0x8],0x2
   0x080483d8 <+13>:mov    DWORD PTR [ebp-0xc],0x3
   0x080483df <+20>:mov    eax,DWORD PTR [ebp-0xc]
   0x080483e2 <+23>:mov    DWORD PTR [esp+0x4],eax
   0x080483e6 <+27>:mov    eax,DWORD PTR [ebp-0x8]
   0x080483e9 <+30>:mov    DWORD PTR [esp],eax
   0x080483ec <+33>:call   0x80483b4 <add>
   0x080483f1 <+38>:mov    DWORD PTR [ebp-0x4],eax
   0x080483f4 <+41>:leave  
   0x080483f5 <+42>:ret
(gdb) disassemble add
Dump of assembler code for function add:
   0x080483b4 <+0>: push   ebp
   0x080483b5 <+1>: mov    ebp,esp
   0x080483b7 <+3>: sub    esp,0x10
   0x080483ba <+6>: mov    eax,DWORD PTR [ebp+0xc]
   0x080483bd <+9>: mov    edx,DWORD PTR [ebp+0x8]
   0x080483c0 <+12>:lea    eax,[edx+eax*1]
   0x080483c3 <+15>:mov    DWORD PTR [ebp-0x4],eax
   0x080483c6 <+18>:mov    eax,DWORD PTR [ebp-0x4]
   0x080483c9 <+21>:leave  
   0x080483ca <+22>:ret 
(gdb) disassemble main
Dump of assembler code for function main:
   0x080483f6 <+0>: push   ebp
   0x080483f7 <+1>: mov    ebp,esp
   0x080483f9 <+3>: sub    esp,0x8
   0x080483fc <+6>: mov    DWORD PTR [esp+0x4],0x3
   0x08048404 <+14>:mov    DWORD PTR [esp],0x2
   0x0804840b <+21>:call   0x80483cb <print>
   0x08048410 <+26>:leave  
   0x08048411 <+27>:ret 

cdecl约定不添加如下指令: 在调用函数之后添加esp 8或其他类似的指令。 为什么这个?谢谢。

1 个答案:

答案 0 :(得分:2)

代码使用leave指令恢复堆栈帧。因此,无需单独调整堆栈指针。