Search code examples
assemblyx86nasmbootloaderreal-mode

bootsector compare always wrong


After you helped me with hlt instruction (I forgot about clear interrupts cli), I found another problem. The compare always clear carry flag whatever buffer is equal or not to right password, in effect the password always is wrong. The problem is with (compare function from osdev.org):

org 0x7c00
bits 16

cld
mov bl,0x0F
mov si, MSGPassword
mov dh,0xA
mov dl,0x2
call printf
call password
mov si, buffer
mov di, VARpassword
call cmpstr
;jc right
;jnc error
hlt
hlt
right:
    mov si,MSGRight
    mov bl,0x03
    call printf
    hlt
error:
    mov si,MSGWrong
    mov bl,0x04
    call printf
    hlt

;definitions

;al - letter to write
;bl - color
;write char at cursor location, then moves its to next column
write:
    mov ah,0x9
    xor bh,bh
    mov cx,0x1
    int 0x10
    mov ah,0x3
    int 0x10
    mov ah,0x2
    inc dl
    int 0x10
    ret
;al - letter to write
;bl - color
; same as write, but dont go to next column
writen:
    mov ah,0x9
    xor bh,bh
    mov cx,0x1
    int 0x10
    ret
;si - message
;bl - colour
;dh - row
;dl - column
;print string
printf:
    mov ah,0x2
    int 0x10
    .loop:
        lodsb
        or al,al
        jz .end
        call write
        jmp .loop
    .end:
        ret

;get password, with write * on screen
;no args
;password is written to buffer
password:
    xor cl,cl
    mov si, buffer
    .loop:
        xor ah,ah
        int 0x16
        cmp al, 0x08
        je .backspace
        cmp al,0x0D
        je .done
        cmp cl, 0x3F
        je .loop

        stosb
        inc cl

        mov al,'*'
        mov bl,0x0F
        call write
        jmp .loop
    .backspace:
        cmp cl,0x0
        je .loop

        dec di
        mov byte [di], 0
        dec cl
        pusha
        mov ah,0x3
        int 0x10
        dec dl
        mov ah,0x2
        int 0x10
        popa
        mov al,' '
        mov bl,0x0F
        call writen
        jmp .loop
    .done:
        mov al,0
        stosb
        ret

;compare string
; di, si - strings to compare
cmpstr:
    .loop:
        mov al,[si]
        mov bl,[di]
        cmp al,bl
        jne .notequal
        cmp al,0x0
        je .equal
        inc di
        inc si
        jmp .loop
    .notequal:
        clc
        ret
    .equal:
        stc
        ret
MSGRight db "Right password", 0x0
MSGWrong db "Wrong password", 0x0
MSGPassword db "Password:",0x0
buffer:
    times 64 db 0x0
VARpassword db "test", 0x0 ;right password
times 0x1FE - ($-$$) db 0x0
db 0x55
db 0xAA

Solution

  • The code in this question is OK, but looking a bit in the code you had posted before @JonathonReinhart edited your post reveals an error!

    You don't input the password in the right place. You setup the SI register where you should setup the DI register. Obviously subsequent comparing will fail.

    password:
     xor cl,cl
     mov si, buffer     <-- Change this to "mov di, buffer"
     .loop: