Mr_Arsonist
Mr_Arsonist

Reputation: 25

Trying to compare two strings in x86-64

global _start

section .data
    firstMsg: db "hello worms, please say the passcode", 10
    firstLen: equ $ - firstMsg
    secondMsg: db "Correct", 10
    secondLen: equ $ - secondMsg
    thirdMsg: db "Incorrect.", 10
    thirdLen: equ $ - thirdMsg
    password: db "Hello"

section .bss
    attempt RESB

section .data
_start:

;Print the first message
    mov rax, 1
    mov rdi, 1
    mov rsi, firstMsg
    mov rdx, firstLen
    syscall

;Read input
    mov rax, 0
    mov rdi, 0
    mov rsi, attempt
    mov rdx, 10
    syscall

;compare input to the password
    cmp attempt, password
    je L1
    jne L2
    syscall

;Display correct if correct
L1:
    mov rax, 1
    mov rdi, 1
    mov rsi, secondMsg
    mov rdx, secondLen
    jmp L3
    syscall

;display incorrect if incorrect
L2:
    mov rax, 1
    mov rdi, 1
    mov rsi, thirdMsg
    mov rdx, secondLen
    syscall

;exit the program
L3:
    mov rax, 60
    mov rdi, 1
    syscall

This code returns this error message:

inout.asm:13: error: invalid combination of opcode and operands
inout.asm:33: error: invalid combination of opcode and operands

What I'm trying to do here is take input from a user as a string, which will then be compared to the constant password. If they are identical, it prints "correct", if they are not it prints "incorrect" and jumps back to the first question (not done that part yet).

If someone can help me bugfix this that'd be pretty cool.

Upvotes: 1

Views: 620

Answers (1)

Chris Dodd
Chris Dodd

Reputation: 126140

a cmp instruction compares two values that fit into a register (8, 16, 32, or 64 bit values), not two strings. You need a cmpsb to compare each character of the strings, and can use a rep with it to compare the whole string in one go:

;compare input to the password
    mov rsi, attempt    ; first string
    mov rdi, password   ; second string
    mov rcx, 5          ; length of the password
    repe cmpsb          ; compare
    jne L2              ; no match
    cmp byte ptr [rsi], 10  ; \n to end the input
    jne L2              ; extra stuff in attempt
    jmp L1

Note that you could simplify this a bit by adding the '\n' character to the expected password and using a length of 6. Then you wouldn't need the extra cmp/jne checking for the end of the input.

Upvotes: 3

Related Questions