Я хочу написать следующий код 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 (% ЭСП) заставить его работать, поэтому мой первый вопрос я прошу разъяснение по этому вопросу. Затем я попытался сделать то же самое с двумя переменными:
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 (% ЭСП), прежде чем Так что мой второй вопрос, как может Я заставить его работать с двумя переменными Спасибо
редактировать:.!? Почему следующий код не будет работать для сканирования двух переменных
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 или еще много чего. Почему бы просто не добавить -4 перед esps (т. Е. Иметь код pushl -4 (% esp) #location x (и тот же для y, перед scanf) сделать трюк? – nodwj
Потому что он не выполняет trick '.Если вы нажимаете esp-4, вы по-прежнему не выделяете память для переменных. –
Итак, если теперь я понимаю проблему, scanf не может перезаписать адрес, если адрес, указанный для scanf, указывает на себя? – nodwj