Я не совсем уверен, какой тип ассемблера вы используете, однако я мог заставить ваш код компилироваться с gcc, поэтому я придерживался вашего стиля форматирования (не говоря о синтаксисе AT & T).
В любом случае, вам следует проверить документацию на scanf
и понять, что она принимает строку формата и указатели на места в памяти, где хранятся считанные значенияin. Он также возвращает количество успешно прочитанных элементов , а не то, что было прочитано.
Теперь сделайте то же самое и проверьте документацию для printf
.Вы увидите, что строка формата необходима для печати вашего номера в удобочитаемой форме.Подходящей строкой формата является "%d\n"
для печати числа и новой строки.
Ваш код теперь может выглядеть примерно так (который компилируется и прекрасно работает для меня с помощью gcc):
.section .rodata
input_format: .string "%d"
output_format: .string "%d\n"
.section .bss
input: .long
.section .text
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
pushl $input # push the ADDRESS of input to have the value stored in it
pushl $input_format # give scanf the ADDRESS of the format string
call scanf # call scanf to get number from the user
addl $8, %esp # clean up the stack
# Note the return value of scanf is passed through eax (same for printf)
pushl input # pass the number to printf BY VALUE
pushl $output_format # pass the ADDRESSS of the output format string to printf
call printf # print input
#return from printf:
movl $0, %eax
movl %ebp,%esp
popl %ebp
ret
Обратите внимание, что я обычно использовал бы db/dw/dd
для выделения памяти в секциях .(ro)data
и .bss
, а не .string
и .long
, поэтому, если эта часть сделана слегка неправильно, вы можете просто исправить ее.
Вы также можете использовать пространство стека для хранения числа, однако вы уже объявили input
, и я хотел оставить код как можно более похожим на тот, который вы имели.То же самое относится ко всему остальному до и после вещей scanf
и printf
, я просто оставил это как ваш код.
EDIT: Вот пример использования стека для созданиялокальная переменная, в отличие от переменной, объявленной в сегменте .bss
или .data
:
.section .rodata
input_format: .string "%d"
output_format: .string "%d\n"
.section .text
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
subl $4, %esp # allocate 4 bytes on the stack for a local variable
# The local variable will be at -4(%ebp)
leal -4(%ebp), %eax # get the ADDRESS of our local variable
pushl %eax # push the ADDRESS of the variable on the stack
pushl $input_format # give scanf the ADDRESS of the format string
call scanf # call scanf to get number from the user
addl $8, %esp # clean up the stack
# Note the return value of scanf is passed through eax (same for printf)
pushl -4(%ebp) # pass the number to printf BY VALUE
pushl $output_format # pass the ADDRESSS of the output format string to printf
call printf # print the input
#return from printf:
movl $0, %eax
movl %ebp,%esp
popl %ebp
ret