3

我对堆栈的目的进行了一些哲学思考,经过一些编码后,我弄清楚了它的强度。唯一在我胃里的就是它是如何与功能一起工作的?我尝试使用通用寄存器创建一些简单的函数来添加两个数字,但我想这不是它在 C 中的工作方式,例如。所有参数、局部变量和结果存储在哪里?

您将如何将其重写为汇编程序?(C 的编译器将如何重写它?)

int function(int a, int &b, int *c){
 return a*(b++)+(*c);
}

我知道这个例子有点糟糕..但是这样我就可以理解所有的可能性

4

3 回答 3

5

您正在寻找的是有关调用约定的信息。函数的调用和返回方式取决于很多因素,包括处理器架构、编译器和操作系统。调用者和被调用者必须就约定达成一致,以便正确传递参数和返回值。

于 2010-03-10T18:46:33.537 回答
5

首先,引用 ( int&) 不在 C 中,只是在 C++ 中。

如果您想查看 gcc 的幕后情况,请使用该-S标志。你不需要有一个实际的程序。

g++ -S func.c

创建一个func.s包含(减去标题等,在 x86 盒子上)的文件:

    .text
.globl __Z8functioniRiPi
__Z8functioniRiPi:
LFB2:
    pushq   %rbp
LCFI0:
    movq    %rsp, %rbp
LCFI1:
    movl    %edi, -4(%rbp)
    movq    %rsi, -16(%rbp)
    movq    %rdx, -24(%rbp)
    movq    -16(%rbp), %rax
    movl    (%rax), %edx
    movl    %edx, %ecx
    imull   -4(%rbp), %ecx
    movq    -24(%rbp), %rax
    movl    (%rax), %eax
    addl    %eax, %ecx
    incl    %edx
    movq    -16(%rbp), %rax
    movl    %edx, (%rax)
    movl    %ecx, %eax
    leave
    ret

请注意 C++ 名称修饰 ( __Z8functioniRiPi)。现在我们给 g++-O2标志:

    .text
    .align 4,0x90
.globl __Z8functioniRiPi
__Z8functioniRiPi:
LFB2:
    pushq   %rbp
LCFI0:
    movq    %rsp, %rbp
LCFI1:
    movl    (%rsi), %ecx
    movl    %ecx, %eax
    imull   %edi, %eax
    addl    (%rdx), %eax
    incl    %ecx
    movl    %ecx, (%rsi)
    leave
    ret

-O3给出相同的代码;真的没有什么可以优化的了。

玩组装很开心。^_^

于 2010-03-10T19:09:55.087 回答
3

Aaron 关于调用约定的说法是正确的答案。对于我个人对该主题的探索,我发现Smashing the Stack For Fun and Profit是一个很好的练习,可以扮演堆栈框架的角色,以及当它被损坏时会发生什么。Finlay 我向黑客推荐汇编入门,它涵盖了重要的汇编器概念以及您可以使用调试器做的有趣事情。

于 2010-03-10T19:00:35.277 回答