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”推送值,而不是立即写入堆栈。