X86调用约定:应该由堆栈传递的参数是只读的? [英] x86 calling convention: should arguments passed by stack be read-only?

查看:187
本文介绍了X86调用约定:应该由堆栈传递的参数是只读的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

看来国家的最先进的编译器处理由堆栈传递的参数为只读。请注意,在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆