本文介绍了在nasm程序集中调用scanf时如何使用寄存器中存储的数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在下面,我试图获得用户的选择并使用它来调用其他函数.我将选择推入堆栈,然后推入格式行,然后调用 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 .datasection .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时如何使用寄存器中存储的数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 09:39