我想在汇编中编写以下 C 代码:
int main(void)
{
int x,y;
scanf("%d%d",&x,&y);
printf("%d%d",x,y);
return 0;
}
首先,我尝试只使用一个整数来扫描/打印:
.section .rodata #read only data section
fmt: .string "%d%d"
.text
.globl main
.type main, @function
main:
pushl %ebp #save the old frame pointer
movl %esp, %ebp #create the new frame pointer
pushl %esp #location of x
pushl $fmt
call scanf
#stack should now have exactly the scanned number x and then the format, as needed for printf.
call printf
movl $0, %eax
movl %ebp, %esp #restore the old stack pointer - release all used memory.
popl %ebp #restore old frame pointer (the caller function frame)
ret
但它没有用。出于某种原因,以下技巧使它起作用(在 printf 之前添加):
addl $4,%esp #pop format
pushl 4(%esp)
pushl $fmt
我不明白为什么 pushl 4(%esp) 会使它起作用,所以对于我的第一个问题,我要求对此事进行澄清。然后我尝试对两个变量做同样的事情:
fmt: .string "%d%d"
[...]
pushl %esp #location of x
pushl %esp #location of y
pushl $fmt
call scanf
但它导致了分割错误。它甚至没有到达 printf 部分,我会尝试这样的事情:
addl $4,%esp #pop format
pushl 8(%esp)
pushl 8(%esp)
pushl $fmt
call printf
(遵循与之前的 pushl 4(%esp) 相同的逻辑。所以我的第二个问题是如何使它与两个变量一起工作。谢谢!
编辑:为什么下面的代码不能用于扫描两个变量?
subl $8,%esp #leave place for two vars
pushl -4(%ebp) #location of x
pushl -8(%ebp) #location of y
pushl $fmt
call scanf