Intel x86 Assembly& Microarchitecture 32位cdecl —处理整数

示例

作为参数(8、16、32位)

8、16、32位整数始终作为全宽度32位值1传递到堆栈中。
无需扩展名(已签名或清零)。
被叫方将只使用全宽值的下部。

//被调用者的C原型
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位值传递到堆栈中,遵循小端字节序约定2,先推送高32位,然后再推送低位。

//被调用者的C原型
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


作为返回值

返回8位整数AL,最终破坏了整体eax。
返回16位整数AX,最终破坏了整体eax。
在中返回32位整数EAX。
在中返回64位整数EDX:EAX,其中EAX包含低32位和EDX高32位。

//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在低位地址