can't compare user input with number, nasm elf64

后端 未结 2 1311
独厮守ぢ
独厮守ぢ 2021-01-27 07:10

I swear I\'ve read more than 20 pages today, from NASM\'s manual to Universities\' guides to Wikipedia to everything in between but I just can\'t wrap my head around this, I wro

相关标签:
2条回答
  • 2021-01-27 07:35

    You need to compare characters, not integer values. Change:

    cmp rcx,0
    

    to

    cmp byte [rcx],'0'
    

    Ditto for the comparison with 1.

    0 讨论(0)
  • 2021-01-27 07:41

    Assuming you're trying to run this on 64 bit AMD64 linux, you need to make sure you use the right way of passing parameters to the kernel (the calling convention).

    For a 64 bit app on linux/x64, it is as follows:

    • rax - system call id
    • rdi - argument 1
    • rsi - argument 2
    • rdx - argument 3
    • r10 - argument 4
    • arg 5 and 6 are in r9 and r8
    • rcx and r11 values are not preserved across syscall, but all other registers will not be clobbered.

    In addition, Paul R's answer is also correct. The ASCII representation of '0' is not decimal zero. Another gotcha is that the stdin operates in buffered mode by default, so you won't actually get any data until you press enter. The code below reads two bytes into the tmp buffer (pointed to by rsi) and compares the first with ascii-zero. The second byte is a newline character that we're not particularly interested in.

    ; constants
    section .data
      lblZero:      db    'Not zero, try again', 0xa;
      tmp:          db    0,0;
    ; code
    
    section .text
    BITS 64
      global _start
    _start: 
      mov rax, 0   ; sys_read(int fd, void *ptr, int count)
      mov rdi, 0   ; 0 = stdin 
      mov rsi, tmp ; @ tmp
      mov rdx, 2   ; 2 bytes (one for our number, another to store newline)
      syscall
      cmp byte[rsi], '0' ; is input '0' (or decimal 48) ? 
      je  done
      mov rax, 1            ; sys_write(int fd, void *ptr, int count)
      mov rdi, 1            ; 1 = stdout
      mov rsi, lblZero      ; @lblZero
      mov rdx, 20           ; 20 bytes
      syscall
      jmp _start
    
    done:   
      mov rax, 60 ; sys_exit
      mov rdi, 0
      syscall
    
    0 讨论(0)
提交回复
热议问题