我对堆栈的目的进行了哲学思考,经过一些编码后,我发现它的强度是多少。我的胃口唯一的东西是它如何与功能一起使用?我尝试使用通用寄存器来添加两个数字,但是我想它不是如何在C中工作的例子..所有参数,局部变量以及存储结果的位置在哪里?
你会如何将它重写为汇编程序?(C编译器如何重写它?)
int function(int a, int &b, int *c){
return a*(b++)+(*c);
}
我知道这个例子有点糟透..但这样我就能理解所有的可能性
答案 0 :(得分:5)
您正在寻找的是有关calling conventions的信息。调用和返回函数的方式取决于许多因素,包括处理器体系结构,编译器和操作系统。调用者和被调用者必须就约定达成一致,以便正确传递参数和返回值。
答案 1 :(得分: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
提供相同的代码;没有什么可以优化的。
玩装配玩得开心。 ^ _ ^
答案 2 :(得分:3)
Aaron关于召集会议的说法是正确的答案。对于我自己对该主题的个人探索,我发现Smashing the Stack For Fun and Profit是一个很好的练习堆栈框架的角色,以及当它被破坏时会发生什么。 Finlay我推荐使用assembly primer for hackers来解决重要的汇编程序概念以及使用调试器可以做的有趣事情。