32 位 cdecl 處理整數
作為引數(8,16,32 位)
8,16,32 位整數總是在堆疊上傳遞為全寬 32 位值 1 。
不需要擴充套件,簽名或歸零。
被呼叫者將只使用全寬值的下半部分。
//C prototype of the callee
void __attribute__((cdecl)) foo(char a, short b, int c, long d);
foo(-1, 2, -3, 4);
;Call to foo in assembly
push DWORD 4 ;d, long is 32 bits, nothing special here
push DWORD 0fffffffdh ;c, int is 32 bits, nothing special here
push DWORD 0badb0002h ;b, short is 16 bits, higher WORD can be any value
push DWORD 0badbadffh ;a, char is 8 bits, higher three bytes can be any value
call foo
add esp, 10h ;Clean up the stack
作為引數(64 位)
使用兩次推送在堆疊上傳遞 64 位值,遵循 littel endian 約定 2 ,首先推高 32 位然後推低位。
//C prototype of the callee
void __attribute__((cdecl)) foo(char a, short b, int c, long d);
foo(0x0123456789abcdefLL);
;Call to foo in assembly
push DWORD 89abcdefh ;Higher DWORD of 0123456789abcdef
push DWORD 01234567h ;Lower DWORD of 0123456789abcdef
call foo
add esp, 08h
作為返回值
在 AL
中返回 8 位整數,最終破壞整個 eax
。
在 AX
中返回 16 位整數,最終破壞整個 eax
。
EAX
中返回 32 位整數。
在 EDX:EAX
中返回 64 位整數,其中 EAX
保持低 32 位而 EDX
保持高位。
//C
char foo() { return -1; }
;Assembly
mov al, 0ffh
ret
//C
unsigned short foo() { return 2; }
;Assembly
mov ax, 2
ret
//C
int foo() { return -3; }
;Assembly
mov eax, 0fffffffdh
ret
//C
int foo() { return 4; }
;Assembly
xor edx, edx ;EDX = 0
mov eax, 4 ;EAX = 4
ret
1 這使堆疊保持 4 位元組對齊,即自然字大小。另外,x86 CPU 在長模式下只能推 2 或 4 個位元組。
2 在較低地址處降低 DWORD