我想写在大会下面的C代码:大会(AT&T 32位)scanf函数的问题
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
现在我明白了一切,除了为什么不得不打扰推动%eax或什么。为什么不简单地在esps之前加-4(例如,使用代码pushl -4(%esp)#x的位置(并且在scanf之前对y是相同的)执行该操作? – nodwj
因为它不会“执行技巧'如果你推esp - 4,你仍然不会为变量分配内存 –
那么,如果我现在理解了这个问题,如果给scanf的地址指向自己,那么scanf不能覆盖这个地址? – nodwj