【问题标题】:scanf issues in nasm assembly program [duplicate]nasm汇编程序中的scanf问题[重复]
【发布时间】:2015-07-22 23:16:22
【问题描述】:

我昨天在问这个问题。今天有机会和教授坐在一起,我们想不通。在调试器中运行时,在 read_int_new 中调用 scanf 后得到以下信息。

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7a6c742 in _IO_vfscanf_internal (s=<optimized out>, 
    format=<optimized out>, argptr=argptr@entry=0x7fffffffdde0, 
    errp=errp@entry=0x0) at vfscanf.c:1857
1857    vfscanf.c: No such file or directory.

他说它似乎设置正确。我已经坚持了一段时间。

代码:

        bits 64
        global  main
        extern  puts
        extern  printf
        extern  scanf   
        extern  get_kb



      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  "%d",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,0
value:  dq  0



.code
main:

menu:
    ;print menu 
    mov edi, menuprompt
    call    puts            ;display menu
    mov edi,choicemsg
    ;mov    eax, 0
    ;call   printf          ;display "Your choice:" 
    call puts
    call    get_kb
    mov bl, al
    cmp bl, 'N' ;N
    je  read_int_new
    cmp bl, 'F' ;F
    je  fib
    cmp bl, 'X' ;X
    je  correct     
    ;else
    jmp menu

;print success!! for debugging purposes
correct:
    mov edi, LC9
    mov eax,0
    call    printf
    jmp     menu

entered_n:
    call    read_int_new
    jmp menu 


read_int_new:
    mov edi, enterintmsg    ;display "Enter an integer 0-20: "
    mov eax, 0
    call    printf

    ;lea    rax, [value]
    ;mov    rsi, rax
    ;mov    rax, value  
    ;mov    rdi, LC5
    ;mov    eax, 0
    ;call   scanf               ;get user input 

    mov rdi, LC5
    ;lea    rsi, [value]    
    mov rax, [value]    
    ;mov    eax,0
    call    scanf


    ;ERROR OCCURS HERE!!!!!!!!!!!!!!!!!!!

    mov edi, LC9            ;test to see if it got here
    mov eax, 0
    call    printf  


    ;test   ebx, ebx            ;compare to 0 (eax-eax=0)
    ;js L9
    ;mov    edi, LC9            ;test to see if it got here
    ;mov    eax, 0
    ;call   printf  

    ;mov    ebx, DWORD [rbp-4]
    ;cmp    ebx, 20             ;jump if greater than 20
    ;jg L9
    ;mov    edi, LC9            ;test to see if it got here
    ;mov    eax, 0
    ;call   printf      

    ;mov    ebx, DWORD [rbp-4]      ;else, jump to L10
    ;mov    edi, LC9            ;test to see if it got here
    ;mov    eax, 0
    ;call   printf      
    ;jmp    L10
    ;leave  
    ;ret
    jmp menu




fib:

    ;mov esi, [value]   
    mov edi, LC9 

    mov eax,0   
    ;mov eax, LC5
    ;push [eax] 
    ;push value
    ;push LC5   
    call printf
    jmp menu

【问题讨论】:

  • 改成这个后不会崩溃 ;mov rdi, LC5 ;lea rsi, [value] mov rax, [value] ;mov eax,0 call scanf can't find the input but
  • 请仅包含您实际运行的代码。所有这些注释掉的指令使代码更难阅读。

标签: assembly nasm scanf


【解决方案1】:

我不知道您的代码中发生了什么(cmets 太多),但如果您不介意使用 64 位绝对地址,您可以通过这种方式调用 scanf

mov rdi, formatString         ;Absolute address!!
mov rsi, intVarible           ;Absolute address!!
xor rax, rax
call scanf

或者你可以使用

lea rdi, [rel formatString]
lea rsi, [rel intVarible]
xor rax, rax
call scanf

不要对方括号的使用感到困惑,它们与lea 指令一起使用,不会访问内存。

与使用printf 打印值相反,您可以使用

lea rdi, [rel formatOutputString]   ;No mem access
mov rsi, QWORD [rel intVarible]     ;Real memory access
xor rax, rax
call printf

绝对地址的使用更清楚(对我而言)但浪费了大量字节。


注意“%d”读取的是int(仍然是32位)。

【讨论】:

  • 我之前尝试过类似的设置。尝试使用这些,在调试器中运行它时仍然遇到相同的错误。获得输入后崩溃。将 %d 更改为 %ld,仍然没有运气。错误是 1057 vfscanf.c:没有这样的文件或目录。 (现在是 1057 而不是 1857)。在研究了大约两周后,我将暂时跳过这个。如果我完成其他所有事情,我会回到它。谢谢!
  • @user3866044 我已经测试了上面的代码并且工作了,也许是别的东西。
  • 可能是时候尝试另一台机器了!谢谢。
猜你喜欢
  • 1970-01-01
  • 2013-12-03
  • 2012-10-11
  • 1970-01-01
  • 1970-01-01
  • 2018-09-08
  • 2014-12-26
  • 2017-12-26
  • 1970-01-01
相关资源
最近更新 更多