- 论坛徽章:
- 2
|
回复 #22 老手 的帖子
我写毕业论文时, 就仔细研究过返回值类型对thunk技术的影响。
应该不会记错。
既然你这么认真, 那我就再写点玩具代码验证一下:
-------- -------- -------- return_structure.c
typedef struct {
int x;
int y;
} Point2D32S;
Point2D32S point2d32s(int x,int y) {
Point2D32S result = {x,y};
return result;
}
typedef struct {
short x;
short y;
} Point2D16S;
Point2D16S point2d16s(short x,short y) {
Point2D16S result = {x,y};
return result;
}
typedef struct {
int val;
} atomic_t;
atomic_t atomic(int val) {
atomic_t result = {val};
return result;
}
-------- -------- -------- msvc6 cl /W3 /O2 /FAs /c return_structure.c /Favc6.asm
PUBLIC _point2d32s
; COMDAT _point2d32s
_TEXT SEGMENT
_x$ = 8
_y$ = 12
_point2d32s PROC NEAR ; COMDAT
; 7 : Point2D32S result = {x,y};
mov eax, DWORD PTR _x$[esp-4]
mov edx, DWORD PTR _y$[esp-4]
; 8 : return result;
; 9 : }
ret 0
_point2d32s ENDP
_TEXT ENDS
PUBLIC _point2d16s
; COMDAT _point2d16s
_TEXT SEGMENT
_x$ = 8
_y$ = 12
_result$ = 8
_point2d16s PROC NEAR ; COMDAT
; 17 : Point2D16S result = {x,y};
mov ax, WORD PTR _x$[esp-4]
mov cx, WORD PTR _y$[esp-4]
mov WORD PTR _result$[esp-4], ax
mov WORD PTR _result$[esp-2], cx
; 18 : return result;
mov eax, DWORD PTR _result$[esp-4]
; 19 : }
ret 0
_point2d16s ENDP
_TEXT ENDS
PUBLIC _atomic
; COMDAT _atomic
_TEXT SEGMENT
_val$ = 8
_atomic PROC NEAR ; COMDAT
; 26 : atomic_t result = {val};
; 27 : return result;
mov eax, DWORD PTR _val$[esp-4]
; 28 : }
ret 0
_atomic ENDP
_TEXT ENDS
END
-------- -------- -------- msvc8 cl /W3 /O2 /FAs /c return_structure.c /Favc8.asm
PUBLIC _point2d32s
_TEXT SEGMENT
_x$ = 8 ; size = 4
_y$ = 12 ; size = 4
_point2d32s PROC ; COMDAT
; 7 : Point2D32S result = {x,y};
mov eax, DWORD PTR _x$[esp-4]
mov edx, DWORD PTR _y$[esp-4]
; 8 : return result;
; 9 : }
ret 0
_point2d32s ENDP
_TEXT ENDS
PUBLIC _point2d16s
; Function compile flags: /Ogtpy
; COMDAT _point2d16s
_TEXT SEGMENT
_result$ = 8 ; size = 4
_x$ = 8 ; size = 2
_y$ = 12 ; size = 2
_point2d16s PROC ; COMDAT
; 17 : Point2D16S result = {x,y};
mov ax, WORD PTR _x$[esp-4]
mov cx, WORD PTR _y$[esp-4]
mov WORD PTR _result$[esp-4], ax
mov WORD PTR _result$[esp-2], cx
; 18 : return result;
mov eax, DWORD PTR _result$[esp-4]
; 19 : }
ret 0
_point2d16s ENDP
_TEXT ENDS
PUBLIC _atomic
; Function compile flags: /Ogtpy
; COMDAT _atomic
_TEXT SEGMENT
_val$ = 8 ; size = 4
_atomic PROC ; COMDAT
; 26 : atomic_t result = {val};
; 27 : return result;
mov eax, DWORD PTR _val$[esp-4]
; 28 : }
ret 0
_atomic ENDP
_TEXT ENDS
END
-------- -------- -------- msvc9 cl /W3 /O2 /FAs /c return_structure.c /Favc9.asm
PUBLIC _point2d32s
_TEXT SEGMENT
_x$ = 8 ; size = 4
_y$ = 12 ; size = 4
_point2d32s PROC ; COMDAT
; 7 : Point2D32S result = {x,y};
mov eax, DWORD PTR _x$[esp-4]
mov edx, DWORD PTR _y$[esp-4]
; 8 : return result;
; 9 : }
ret 0
_point2d32s ENDP
_TEXT ENDS
PUBLIC _point2d16s
; Function compile flags: /Ogtpy
; COMDAT _point2d16s
_TEXT SEGMENT
_result$ = 8 ; size = 4
_x$ = 8 ; size = 2
_y$ = 12 ; size = 2
_point2d16s PROC ; COMDAT
; 17 : Point2D16S result = {x,y};
mov ax, WORD PTR _x$[esp-4]
mov cx, WORD PTR _y$[esp-4]
mov WORD PTR _result$[esp-4], ax
mov WORD PTR _result$[esp-2], cx
; 18 : return result;
mov eax, DWORD PTR _result$[esp-4]
; 19 : }
ret 0
_point2d16s ENDP
_TEXT ENDS
PUBLIC _atomic
; Function compile flags: /Ogtpy
; COMDAT _atomic
_TEXT SEGMENT
_val$ = 8 ; size = 4
_atomic PROC ; COMDAT
; 26 : atomic_t result = {val};
; 27 : return result;
mov eax, DWORD PTR _val$[esp-4]
; 28 : }
ret 0
_atomic ENDP
_TEXT ENDS
END
如果你看不懂intel的汇编格式, 这里还有at &t的。
-------- -------- -------- gcc4.4.0 gcc -Wall -O2 -S return_structure.c -o gcc4.4.0.s
.p2align 2,,3
.globl _point2d32s
.def _point2d32s; .scl 2; .type 32; .endef
_point2d32s:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax
movl 12(%ebp), %edx
leave
ret
.p2align 2,,3
.globl _point2d16s
.def _point2d16s; .scl 2; .type 32; .endef
_point2d16s:
pushl %ebp
movl %esp, %ebp
movzwl 12(%ebp), %eax
sall $16, %eax
movw 8(%ebp), %ax
leave
ret
.p2align 2,,3
.globl _atomic
.def _atomic; .scl 2; .type 32; .endef
_atomic:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax
leave
ret
-------- -------- -------- gcc3.4.5 gcc -Wall -O2 -S return_structure.c -o gcc3.4.5.s
.p2align 4,,15
.globl _point2d32s
.def _point2d32s; .scl 2; .type 32; .endef
_point2d32s:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax
movl 12(%ebp), %edx
popl %ebp
ret
.p2align 4,,15
.globl _point2d16s
.def _point2d16s; .scl 2; .type 32; .endef
_point2d16s:
pushl %ebp
andl $-65536, %eax
movl %esp, %ebp
movzwl 8(%ebp), %edx
orl %edx, %eax
andl $65535, %eax
movzwl 12(%ebp), %edx
popl %ebp
sall $16, %edx
orl %edx, %eax
ret
.p2align 4,,15
.globl _atomic
.def _atomic; .scl 2; .type 32; .endef
_atomic:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax
popl %ebp
ret
-------- -------- -------- 总结
Point2D32S 返回值在eax, edx中。
Point2D16S 返回值压缩到eax中。
atomic_t 返回值在eax中。
如果gcc加上 -fomit-frame-pointer, 应该会生成完全相同的代码。 |
|