Search code examples
assemblyx86user-inputnasm

Comparing characters with user input


I am having a problem with comparing declared constants in the .data section with user variables in the .bss section, where I will store user input from syscall read.
They both are doublewords. Could there be a problem with linefeeds? Maybe the user inputs every time a set of characters with a linefeed? Neither the linker nor NASM reports any errors. I think that my code executes as it should, but the comparison fails every time (comparing always results in the zero flag being set to 0).
Thanks a bunch! Trying to understand NASM better.

My code:

SECTION .data
zprava db 'ahoj',0Ah

porovnat dd 'start'

SECTION .bss
input resd 1 

SECTION .text
global _start

_start:

mov edx,5 
mov ecx,input
mov ebx,0
mov eax,3
int 80h
cmp dword [input], porovnat
jz dal
jnz konec

dal:
mov edx,5 ;4 characters + linefeed
mov ecx,zprava
mov ebx,1
mov eax,4
int 80h
jmp konec

konec:
mov ebx,0
mov eax,1
int 80h

I was expecting the message "ahoj" to be outputted in the console.


Solution

  • porovnat dd 'start'
    SECTION .bss input resd 1
    

    They both are doublewords

    Having used dd on this string constant will define 2 dwords. Your porovnat is equivalent to: db 'start', 0, 0, 0. Normally you don't need these extra zeroes, so just write it with a db directive: porovnat db 'start'.
    The resd 1 does reserve one dword but then later you allow 5 bytes to be read into this buffer. Better write input resb 5.

    cmp dword [input], porovnat
    

    the comparing fails every time (comparing always results in the zero flag being set to 0).

    In NASM you get the address if you don't surround with a couple of square brackets. So this instruction is not comparing to the contents at porovnat. And since you can't have two memory references in the same instruction, you need to load one of them in a register: mov eax, [input] cmp eax, [porovnat].


    SECTION .data
     zprava   db 'ahoj', 10
     porovnat db 'start'
    
    SECTION .bss
     input resb 5
    
    SECTION .text
     global _start
    
    _start:
    
    mov edx,5
    mov ecx,input
    mov ebx,0
    mov eax,3
    int 80h
    
    mov eax, [input]        ; load first 4 characters
    cmp eax, [porovnat]     ; compare to 'star'
    jne konec
    mov al, [input+4]       ; load the fifth character
    cmp al, [porovnat+4]    ; compare to 't'
    jne konec
    
    mov edx,5
    mov ecx,zprava
    mov ebx,1
    mov eax,4
    int 80h
    
    konec:
    mov ebx,0
    mov eax,1
    int 80h