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

Assembly 在_start函数(x86 ASM)中作为局部变量写入堆栈,assembly,x86,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) Lo

我正在编写一个编译器——或者类似的东西——我正在生成简单的、未优化的汇编代码

代码是有效的,除了一件事

我知道
%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)
但是,下面的代码是从我的编译器输出的,它在我试图在
\u start
中分配给
-8(%esp)
的第一行出现故障。在
功能中执行相同的操作两次
不会出现故障

似乎在_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);
}

通常,如果使用EBP作为指向本地堆栈帧的指针,则在调用sub之前不会写入它所指向的位置。相反,您只需将其推送到ESP,并将其留给sub相应地设置EBP,这样您就可以读取以前推送到ESP的位置。因此,如果使用“传统”堆栈帧,则使用EBP是不正确的。

如果要使用EBP,您的工作是初始化
EBP
。请注意,您在
中两次执行了
mov%esp,%ebp
,但在
\u start
中未执行此操作。另外,实际分配您尝试使用的空间也是一个好主意(通常由
subl$size,%esp
)完成。将相当于“enter”微码指令的代码编写出来(这是一件好事)表明您可能也希望对“leave”指令执行同样的操作。初始化%ebp指针就成功了!谢谢你!你说得对。因此,我现在所做的只是使用“pushl”推送值,而不是立即写入堆栈。