输入后,scanf在程序集中停止程序

时间:2015-07-07 14:49:24

标签: assembly nasm scanf

在read_int函数中,在用户输入数字并点击进入后,程序就会停止。我已经尝试了几件事(有些已经注释掉了)但却无法使吸盘工作。

    bits 64
    global  main
    extern  puts
    extern  printf
    extern  scanf



    section .data
LC0:    db  'Invalid Input. Enter N,F, or X',0x0D,0x0a,0
LC1:    db  'Number equals: '
LC2:    db  "%d"
LC3:    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
LC4:    db  "Your Choice: ",0
LC5:    db  "%s",0
LC6:    db  "Enter and integer 0-20: ",0
LC7:    db  'Enter a valid number between 0 and 20',0x0D,0x0a,0
LC9:    db  'Success!',0x0D,0x0a,0

        section .text
main: 
LFB0:
    push    rbp 
    mov rbp, rsp
    sub rsp, 32
    mov DWORD [rbp-20], edi 
    mov QWORD [rbp-32], rsi
    mov DWORD [rbp-4], 0
    mov BYTE [rbp-5], 79
    jmp L2
L5:
    mov eax, 0
    call    menu
    cmp eax, 'N'    
    je  read_int    
    cmp eax, 'F'    
    je  display 
    cmp eax, 'X'    
    je  L3
    ;mov    edi, LC0
    ;call   puts
    ;jmp    L2          ;need an else (not N,F,X) 

L3:
    cmp BYTE [rbp-5], 78
    jne L4
    mov eax, DWORD [rbp-4]
    mov edi, eax
    call    read_int
    mov DWORD [rbp-4], eax
    mov edi, LC1
    mov eax, 0
    call    printf
    mov eax, DWORD [rbp-4]
    mov esi, eax
    mov edi, LC2
    mov eax, 0
    call    printf
    jmp L2

L4:
    cmp BYTE [rbp-5], 70
    jne L2
    mov eax, DWORD [rbp-4]
    mov edi, eax
    call    display



L2:
    cmp BYTE [rbp-5], 88
    jne L5
    leave
    ret



menu:
LFB1:

    push    rbp
    mov rbp, rsp
    sub rsp, 16

    mov edi, LC3
    call    puts            ;display menu
    mov edi,LC4
    mov eax, 0
    call    printf          ;display "Your choice: "    
    lea rax, [rbp-1]
    mov rsi, rax
    mov edi,LC5
    mov eax, 0
    call    scanf
    movzx   eax, BYTE [rbp-1]
    leave
    ret



read_int:
LFB2:

    push    rbp
    mov rbp, rsp
    sub rsp, 16

    mov DWORD [rbp-4], edi
    mov DWORD [rbp-4], 0
    mov edi, LC6            ;display "Enter an integer 0-20: "
    mov eax, 0
    call    printf

    lea rax, [rbp-4]
    mov rsi, rax
    mov edi, LC2
    mov eax, 0
    call    scanf               ;get user input
    mov ebx, DWORD [rbp-4]

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


    ;test   eax, eax            ;compare to 0 (eax-eax=0)
    ;js L9
    ;mov    eax, DWORD [rbp-4]
    ;cmp    eax, 20             ;jump if greater than 20
    ;jg L9
    ;mov    eax, DWORD [rbp-4]      ;else, jump to L10
    ;jmp    L10
    leave   
    ret
L9:
    mov edi, LC7            ;if not valid, print enter valid integer
    mov eax, 0
    call    printf  
    mov eax, DWORD [rbp-4]
    mov edi, eax
    call    read_int


L10:
    ;push DWORD [rbp-4] 
    leave
    ret
    ;jmp main


LC8:    db  " , "




display:
LFB3:

    push    rbp
    mov rbp, rsp
    sub rsp, 32
    mov DWORD [rbp-20], edi
    mov DWORD [rbp-4], 0
    jmp L12
L13:
    mov eax, DWORD [rbp-4]
    mov esi, eax
    mov edi, LC2
    mov eax, 0
    call    printf
    mov edi, LC8
    mov eax, 0
    call    printf
    add DWORD [rbp-4], 1
L12:
    mov eax, DWORD [rbp-4]
    cmp eax, DWORD [rbp-20]
    jle L13
    leave
    ret





    ; function return
    mov     eax, 0
    add     rsp, 32
    pop     rbp
    ret

获取用户输入行后,应该跳回菜单,以便用户输入F打印数字0号。我仍然需要处理函数的检查范围部分,但是现在我只是想让它返回main。

我得到以下输出。该程序在点击进入后冻结。

Enter N to enter an integer from 0 to 20
Enter F to display the first N+1 numbers (beginning with zero) on the console
Enter X to quit the program

Your Choice: N
Enter and integer 0-20:  5
^C

1 个答案:

答案 0 :(得分:0)

正如Frank Kotler所说,零终止LC2解决了这个问题。