對於下面的C代碼:調用約定函數返回結構
struct _AStruct {
int a;
int b;
float c;
float d;
int e;
};
typedef struct _AStruct AStruct;
AStruct test_callee5();
void test_caller5();
void test_caller5() {
AStruct g = test_callee5();
AStruct h = test_callee5();
}
我得到以下拆裝的Win32:
_test_caller5:
00000000: lea eax,[esp-14h]
00000004: sub esp,14h
00000007: push eax
00000008: call _test_callee5
0000000D: lea ecx,[esp+4]
00000011: push ecx
00000012: call _test_callee5
00000017: add esp,1Ch
0000001A: ret
而對於linux32鏡像:
00000000 <test_caller5>:
0: push %ebp
1: mov %esp,%ebp
3: sub $0x38,%esp
6: lea 0xffffffec(%ebp),%eax
9: mov %eax,(%esp)
c: call d <test_caller5+0xd>
11: sub $0x4,%esp ;;;;;;;;;; Note this extra sub ;;;;;;;;;;;;
14: lea 0xffffffd8(%ebp),%eax
17: mov %eax,(%esp)
1a: call 1b <test_caller5+0x1b>
1f: sub $0x4,%esp ;;;;;;;;;; Note this extra sub ;;;;;;;;;;;;
22: leave
23: ret
我試圖瞭解呼叫後呼叫方的不同表現。 爲什麼Linux32中的調用者做這些額外的潛艇?
我會假設兩個目標都遵循cdecl調用約定。 cdecl是否定義了返回結構的函數的調用約定?
編輯:
我添加了被調用者的實現。果然,你可以看到linux32鏡像,被叫彈出它的參數,而在Win32被叫方不:
AStruct test_callee5()
{
AStruct S={0};
return S;
}
的Win32拆解:
test_callee5:
00000000: mov eax,dword ptr [esp+4]
00000004: xor ecx,ecx
00000006: mov dword ptr [eax],0
0000000C: mov dword ptr [eax+4],ecx
0000000F: mov dword ptr [eax+8],ecx
00000012: mov dword ptr [eax+0Ch],ecx
00000015: mov dword ptr [eax+10h],ecx
00000018: ret
linux32鏡像,拆卸:
00000000 <test_callee5>:
0: push %ebp
1: mov %esp,%ebp
3: sub $0x20,%esp
6: mov 0x8(%ebp),%edx
9: movl $0x0,0xffffffec(%ebp)
10: movl $0x0,0xfffffff0(%ebp)
17: movl $0x0,0xfffffff4(%ebp)
1e: movl $0x0,0xfffffff8(%ebp)
25: movl $0x0,0xfffffffc(%ebp)
2c: mov 0xffffffec(%ebp),%eax
2f: mov %eax,(%edx)
31: mov 0xfffffff0(%ebp),%eax
34: mov %eax,0x4(%edx)
37: mov 0xfffffff4(%ebp),%eax
3a: mov %eax,0x8(%edx)
3d: mov 0xfffffff8(%ebp),%eax
40: mov %eax,0xc(%edx)
43: mov 0xfffffffc(%ebp),%eax
46: mov %eax,0x10(%edx)
49: mov %edx,%eax
4b: leave
4c: ret $0x4 ;;;;;;;;;;;;;; Note this ;;;;;;;;;;;;;;
不開始用下劃線標識變化:這些名字是保留給編譯器+ libc實現;因爲這是新語言關鍵字使用的起始標識符(例如`_Bool`,C99和`_Alignas`的`_Complex`,C1x的`_Generic`) – Christoph 2011-02-08 09:47:10
您是否也可以反彙編函數本身?然後,您可能會在Windows中找到該功能並提供額外的說明。如上所述,這沒有標準。 「cdecl」,「stdcall」等等不是C/C++標準的一部分。 – Lundin 2011-02-08 09:57:12