X86调用约定:应该由堆栈传递的参数是只读的? [英] x86 calling convention: should arguments passed by stack be read-only?
问题描述
看来国家的最先进的编译器处理由堆栈传递的参数为只读。请注意,在x86调用约定,调用者的论点推到堆栈和被叫使用的参数在堆栈中。例如,下面的C code:
It seems state-of-art compilers treat arguments passed by stack as read-only. Note that in the x86 calling convention, the caller pushes arguments onto the stack and the callee uses the arguments in the stack. For example, the following C code:
extern int goo(int *x);
int foo(int x, int y) {
goo(&x);
return x;
}
是铛-O3 -c g.c -S -m32
在OS X 10.10到编译:
is compiled by clang -O3 -c g.c -S -m32
in OS X 10.10 into:
.section __TEXT,__text,regular,pure_instructions
.macosx_version_min 10, 10
.globl _foo
.align 4, 0x90
_foo: ## @foo
## BB#0:
pushl %ebp
movl %esp, %ebp
subl $8, %esp
movl 8(%ebp), %eax
movl %eax, -4(%ebp)
leal -4(%ebp), %eax
movl %eax, (%esp)
calll _goo
movl -4(%ebp), %eax
addl $8, %esp
popl %ebp
retl
.subsections_via_symbols
这里,参数 X
( 8(%EBP)
)首先被装载到%EAX
;然后存储在 -4(%EBP)
;而地址 -4(%EBP)
存储在%EAX
;和%EAX
传递给函数咕
。
Here, the parameter x
(8(%ebp)
) is first loaded into %eax
; and then stored in -4(%ebp)
; and the address -4(%ebp)
is stored in %eax
; and %eax
is passed to the function goo
.
我不知道为什么锵产生code复制了8(EBP%)到 -4(%EBP)存储在
值
,而不是仅仅通过地址 8(%EBP)
给函数咕
。这将节省内存操作并导致更好的性能。我观察到GCC中类似的行为太(下OS X)。更具体地讲,我不知道为什么编译器不产生:
I wonder why Clang generates code that copy the value stored in 8(%ebp)
to -4(%ebp)
, rather than just passing the address 8(%ebp)
to the function goo
. It would save memory operations and result in a better performance. I observed a similar behaviour in GCC too (under OS X). To be more specific, I wonder why compilers do not generate:
.section __TEXT,__text,regular,pure_instructions
.macosx_version_min 10, 10
.globl _foo
.align 4, 0x90
_foo: ## @foo
## BB#0:
pushl %ebp
movl %esp, %ebp
subl $8, %esp
leal 8(%ebp), %eax
movl %eax, (%esp)
calll _goo
movl 8(%ebp), %eax
addl $8, %esp
popl %ebp
retl
.subsections_via_symbols
我搜索的文件,如果x86的调用约定要求进行只读传递的参数,但我找不到在这个问题上任何东西。没有任何人有任何关于此问题的思想?
I searched for documents if the x86 calling convention demands the passed arguments to be read-only, but I couldn't find anything on the issue. Does anybody have any thought on this issue?
推荐答案
其实,我只是编译使用GCC这个功能:
Actually, I just compiled this function using GCC:
int foo(int x)
{
goo(&x);
return x;
}
和它产生的这种code:
And it generated this code:
_foo:
pushl %ebp
movl %esp, %ebp
subl $24, %esp
leal 8(%ebp), %eax
movl %eax, (%esp)
call _goo
movl 8(%ebp), %eax
leave
ret
这是使用GCC 4.9.2(上,如果它的事项32位Cygwin的),没有优化。所以事实上,海湾合作委员会做了什么你认为它应该做的,直接从那里调用者又将其在堆栈上使用的参数。
This is using GCC 4.9.2 (on 32-bit cygwin if it matters), no optimizations. So in fact, GCC did exactly what you thought it should do and used the argument directly from where the caller pushed it on the stack.
这篇关于X86调用约定:应该由堆栈传递的参数是只读的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!