0

My goal is to create a high/low game where my computer does a simple calculation of half way between the last two possible numbers it could be. It asks, "Am I getting warmer?" The thing I need to get it going (and I don't know if this is nasm specific or something) is knowledge of why the cmp instruction isn't working. I've tried several answers and they do not work.

I tried using

mov r8w, 'Y'

I have also tried

mov r8w, 59h

Both to compare to the word register r8w. I want to know where in my code I'm skipping the logic. Here's the code.

.loop:

        mov rax, 1
        mov rdi, 1
        mov rsi, hot_cold
        mov rdx, w_len
        syscall

        mov r9w, 0
        mov rax, 0              ; setup for input
        mov rbx, 0              ;
        mov rdi, 2              ;
        mov si, r9w             ; collect input
        syscall                 ; init collection

        mov r8w, 0              ;
        mov r8w, 'Y'            ; 59h
        cmp r9w, r8w            ; compare to Y
        jne .hop_no             ; compare fail, try N
        jmp _for_y              ; compare success, change numbers
        ;syscall
        jmp .loop               ; loop on successful Y

.hop_no:
        mov r8w, 0
        mov r8w, 'N'            ;4Eh
        cmp r8w, r9w            ; compare to N
        jne _exit               ; compare fail, exit
        call _for_n             ; compare success change numbers
        ;syscall                                                                                                                                                                                                           
        jmp .loop
Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
onex4
  • 3
  • 3
  • @PeterCordes Okay, so the (strace is awesome) EFAULT is happening. I says bad address. What can I do to clear that variable? – onex4 Mar 16 '20 at 03:28
  • You can read [How to read input from STDIN in x86\_64 assembly?](https://stackoverflow.com/q/9646796) which I linked in my answer. – Peter Cordes Mar 16 '20 at 03:51
  • If the instruction set can't do something in one instruction, then use two or more instructions! – Erik Eidt Mar 16 '20 at 15:25

1 Answers1

1

Two literals? As in assemble-time-constant values like 1234 or 'Y'? That's normally useless because you can just figure out the result yourself, or use %if to let the assembler do it at assemble time. i.e. optimize away the cmp instead of writing instructions that set and read FLAGS.

But if you insist, cmp can take at most one immediate operand, so mov-immediate the other constant number to a register first.

    mov  eax, 'Y'
    cmp  AL, 'Y'

This sets flags:

  • ZF=1 because 'Y' - 'Y' = 0
  • CF=OF=0 because no borrow, and no signed overflow
  • SF=0

(Also PF and AF are written.)


re: your actual code that tries to compare a runtime variable I/O result with an integer literal constant 'Y'

It looks like you think you can read bytes into a register. This is not the case. There is no system-call equivalent to getchar. mov si, r9w copies the contents (leaving the high 6 bytes of RSI unmodified), not setting SI = the address of R9W. Registers do not have addresses.

Read into a buffer (e.g. on the stack) and then load that into a register. How to read input from STDIN in x86_64 assembly? Or use cmp with a memory operand.

Use strace ./my_program to see what system calls you're making and what error code or success they return.

The 64-bit calling convention doesn't pass an arg in RBX. I think mov rbx, 0 is a typo for mov edx, 2. (You seem to have your length and FD args mixed up, too.) You want RDI=fd=0, RDX=length=2. (Or more, in case the user types a longer line).

RSI needs to point to memory for read(int fd, void *buf, size_t len). You have the high 6 bytes of RSI set from the address of hot_cold, but the low 2 bytes set to zero from copying r9w for no apparent reason. This might make it return -EFAULT, or you might be just writing somewhere else in your .data section.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
  • Why am I just looping now? I did all you said, but It doesn't go do anything. Do you want me to update the code? – onex4 Mar 16 '20 at 03:57