我正在编写一个编译器 - 或者看起来像它的东西 - 我正处于生成简单,未优化汇编代码的部分。
代码有效,除了一件事。
我了解%esb
和%esp
在函数调用中的工作原理如下:
Parameter #N -> N*4+4(%ebp)
Parameter 2 -> 12(%ebp)
Parameter 1 -> 8(%ebp)
Return Address -> 4(%ebp)
Old %ebp -> (%ebp)
Local Variable 1 -> -4(%ebp)
Local Variable 2 -> -8(%ebp) and (%esp)
但是,下面的代码是从我的编译器输出的,我尝试在-8(%esp)
中分配给_start
的第一行是段错误。在twice
函数中执行相同操作不会出现段错误。
似乎在_start函数中我无法在堆栈中存储“局部变量”,我想知道我应该如何解决这个问题?
该计划:
.section .data
.section .text
.globl _start
.globl twice
.type twice, @function
twice:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax
movl 8(%ebp), %ebx
addl %eax, %ebx
movl %ebx, -4(%ebp)
movl %ebx, %eax
movl %eax, -8(%ebp)
movl %eax, -8(%ebp)
end_twice:
leave
ret
_start:
movl $10, %eax
movl %eax, -8(%ebp)
movl $10, %eax
pushl %eax
call twice
addl $4, %esp
movl %eax, -8(%ebp)
movl %eax, %ebx
# Exit stuff.
movl $1, %eax
int $0x80
原始输入:
int twice(int x)
{
return x+x;
}
int main()
{
int x;
x = 10;
x = multiply(x);
}
答案 0 :(得分:1)
通常,如果使用EBP作为指向本地堆栈帧的指针,则在调用sub之前不要写入它指向的位置。相反,你只需按下ESP,然后将它留给sub来相应地设置EBP,这样你就可以从之前的ESP推送到ESP。因此,如果使用“传统”堆栈帧,则使用EBP是不正确的。