为程序集中的局部变量创建空间
问题描述:
所以我必须编写一个调用extern C函数的汇编程序。所以我写了简单的pow
函数,我用这个C代码编译我的汇编程序。一切正常。但正如我从gcc
的-S
命令看到的那样,编译器为局部变量创建了一个空间。我认为它会是这样的:为程序集中的局部变量创建空间
int func(int number)
{
int a = 10;
int b = 5;
int c = 0;
}
我们有3个局部变量,所以编译器会subl $12, %esp
。但它适用于subl $16, %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 $5, %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 $0, %eax
leave
ret
func.c
:
int _pow(int number)
{
return number * number;
}
它按预期工作,./main
打印出25
。但是现在,我没有任何东西从%esp
。我的意思是我可以添加这一行,但它不会改变任何东西。我通过互联网搜索,发现也许我的代码只是偶然的工作,通常我应该递减%esp
。所以我的问题在于:通过main
,我应该减少%esp
的值?应该是12
还是16
?
答
由于您正在调用32位C函数,因此您必须遵循C calling convention。与64位系统不同,没有明确的对齐堆栈的顺序。我找不到当这样一个对齐应该发生的声明。按下参数后堆栈可能“未对齐”。
如果你要对齐的堆栈,你可以简单-16后,你救了它(movl %esp, %ebp
):
andl $-16, %esp ; Align 16
采用'16'很可能保持一致堆栈16字节。 – unwind
我想你是对的,但是我应该让它总是16字节对齐,还是应该subl特定值? – Frynio
该要求可能在平台的应用程序二进制接口(ABI)文档中指定。既然它是一个规范,你应该遵循它以便能够与其他代码交互。 – unwind