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