In the following, I'm trying to get the user's choice and use it to call other functions. I'm pushing choice onto the stack, then pushing the format line, then calling scanf, but I can't seem to be able to use what was entered.
;nasm -f elf64 fib.asm -o fib.o
;gcc -S -masm=intel fib.c -o fib.s
;./fib
bits 64
global main
extern puts
extern printf
extern scanf
section .data
errormsg: db 'Invalid Input. Enter N,F, or X',0x0D,0x0a,0
numequalsmsg: db 'Number equals: '
LC2: db "%d",0
menuprompt: db 0x0D,0x0a,'Enter N to enter an integer from 0 to 20',0x0D,0x0a,'Enter F to display the first N+1 numbers (beginning with zero) on the console',0x0D,0x0a,'Enter X to quit the program',0x0D,0x0a,0
choicemsg: db "Your Choice: ",0
LC5: db "%s",0
enterintmsg: db "Enter and integer 0-20: ",0
enternummsg: db 'Enter a valid number between 0 and 20',0x0D,0x0a,0
LC8: db " , ",0
LC9: db 'Success!',0x0D,0x0a,0
LC10: db 'In L10!',0x0D,0x0a,0
LC11: db 'In L12!',0x0D,0x0a,0
LC13: db 'In compare to zero section',0x0D,
value: dw 0
choice: dw 0
section .text
main:
menu:
push rbp
mov rbp, rsp
sub rsp, 16
mov edi, menuprompt
call puts ;display menu
mov edi,choicemsg
mov eax, 0
call printf ;display "Your choice: "
;call getn
push choice
push LC5 ;string format
call scanf ;stores input in choice
;GetLInt [choice]
mov ebx, choice
cmp ebx, 78
je correct
correct:
mov edi, ebx
mov eax,0
call printf
(editor's note: section.data
is just a label declaration like foo.bar:
, and so is .code
. Probably you wanted section .data
and section .text
instead of having everything in the read-only .text
section, since you want scanf to store a result there. I fixed this for you because this old question and the answer weren't about those errors.)
You are using the wrong convention. Obviously you know what you should do, since you had no problem calling printf
. You should use the same convention for calling scanf
too - the stack argument passing that you used is the 32 bit convention, 64 bit uses registers. Something like this:
lea rdi, [LC5] ; 1st arg = format
lea rsi, [choice] ; 2nd arg = address of buffer
xor eax, eax ; no xmm registers
call scanf ; stores input in choice
By the way, using an unconstrained %s
with 2 bytes of space is a bad idea.
Also, do what Frank said, ie. load a byte (mov bl, [choice]
) when you want to process the input.