在汇编中为局部变量创建 space
Making a space for local variables in assembly
所以我必须编写一个调用 extern C 函数的汇编程序。所以我写了简单的 pow
函数,我用这个 C 代码编译了我的汇编程序。一切正常。但是正如我从 gcc
的 -S
命令中看到的那样,编译器为局部变量创建了 space。我以为会是这样:
int func(int number)
{
int a = 10;
int b = 5;
int c = 0;
}
我们有 3 个局部变量,因此编译器会 subl , %esp
。但它适用于 subl , %esp
。即使我在这里只留下一个数字,它仍然会减少16
。现在我有了我的代码:
main.s
:
.section .data
.XD:
msg: .ascii "%d\n"
msg_len = . - msg
.text
.globl _pow
.globl main
main:
pushl %ebp
movl %esp, %ebp
movl , %eax #like int a = 5;
pushl %eax
call _pow #_pow(a);
movl %eax, -8(%ebp)
pushl -8(%ebp)
pushl $.XD
call printf #printf("%d\n", _pow(a));
movl [=12=], %eax
leave
ret
func.c
:
int _pow(int number)
{
return number * number;
}
它按预期工作,./main
打印出 25
。但是现在,我subl
%esp
什么都没有了。我的意思是我可以添加这一行,但它不会改变任何东西。我在互联网上搜索过,发现也许我的代码工作只是偶然,通常我应该减少 %esp
。所以我的问题是:我应该在 main
中减少 %esp
的值是多少?应该是 12
还是 16
?
由于调用 32 位 C 函数,因此必须遵循 C calling convention。与 64 位系统不同,没有明确的堆栈对齐顺序。我找不到 何时 这样的对齐应该发生的声明。压入参数后堆栈可能是"misaligned"。
如果您想对齐堆栈,您可以在保存后简单地执行 AND -16 (movl %esp, %ebp
):
andl $-16, %esp ; Align 16
所以我必须编写一个调用 extern C 函数的汇编程序。所以我写了简单的 pow
函数,我用这个 C 代码编译了我的汇编程序。一切正常。但是正如我从 gcc
的 -S
命令中看到的那样,编译器为局部变量创建了 space。我以为会是这样:
int func(int number)
{
int a = 10;
int b = 5;
int c = 0;
}
我们有 3 个局部变量,因此编译器会 subl , %esp
。但它适用于 subl , %esp
。即使我在这里只留下一个数字,它仍然会减少16
。现在我有了我的代码:
main.s
:
.section .data
.XD:
msg: .ascii "%d\n"
msg_len = . - msg
.text
.globl _pow
.globl main
main:
pushl %ebp
movl %esp, %ebp
movl , %eax #like int a = 5;
pushl %eax
call _pow #_pow(a);
movl %eax, -8(%ebp)
pushl -8(%ebp)
pushl $.XD
call printf #printf("%d\n", _pow(a));
movl [=12=], %eax
leave
ret
func.c
:
int _pow(int number)
{
return number * number;
}
它按预期工作,./main
打印出 25
。但是现在,我subl
%esp
什么都没有了。我的意思是我可以添加这一行,但它不会改变任何东西。我在互联网上搜索过,发现也许我的代码工作只是偶然,通常我应该减少 %esp
。所以我的问题是:我应该在 main
中减少 %esp
的值是多少?应该是 12
还是 16
?
由于调用 32 位 C 函数,因此必须遵循 C calling convention。与 64 位系统不同,没有明确的堆栈对齐顺序。我找不到 何时 这样的对齐应该发生的声明。压入参数后堆栈可能是"misaligned"。
如果您想对齐堆栈,您可以在保存后简单地执行 AND -16 (movl %esp, %ebp
):
andl $-16, %esp ; Align 16