在_start函数中写入堆栈作为局部变量(x86 ASM)

时间:2014-06-11 22:51:35

标签: assembly x86

我正在编写一个编译器 - 或者看起来像它的东西 - 我正处于生成简单,未优化汇编代码的部分。

代码有效,除了一件事。

我了解%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);
}

1 个答案:

答案 0 :(得分:1)

通常,如果使用EBP作为指向本地堆栈帧的指针,则在调用sub之前不要写入它指向的位置。相反,你只需按下ESP,然后将它留给sub来相应地设置EBP,这样你就可以从之前的ESP推送到ESP。因此,如果使用“传统”堆栈帧,则使用EBP是不正确的。