问题描述
在下面,我试图获得用户的选择并使用它来调用其他函数.我将选择推入堆栈,然后推入格式行,然后调用 scanf,但我似乎无法使用输入的内容.
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
(编者注:section.data
只是一个类似于 foo.bar:
的标签声明,.code
也是如此.可能你想要 section .data
和 section .text
而不是在只读 .text
部分中包含所有内容,因为您希望 scanf 存储结果那里.我为您解决了这个问题,因为这个老问题和答案与这些错误无关.)
(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.)
推荐答案
您使用了错误的约定.显然你知道你应该做什么,因为你调用 printf
没有问题.您也应该使用相同的约定来调用 scanf
- 您使用的堆栈参数传递是 32 位约定,64 位使用寄存器.像这样:
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
顺便说一句,使用具有 2 个字节空间的无约束 %s
是个坏主意.
By the way, using an unconstrained %s
with 2 bytes of space is a bad idea.
另外,按照弗兰克说的去做,即.当你想要处理输入时加载一个字节 (mov bl, [choice]
).
Also, do what Frank said, ie. load a byte (mov bl, [choice]
) when you want to process the input.
这篇关于在nasm程序集中调用scanf时如何使用寄存器中存储的数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!