Is this an overflow, or maybe more keyboard data?

53 views Asked by At

I am writing a bootloader, and it's functionality is basically limited to printing a string, then copying keyboard characters to the screen as they are typed. While writing the routines that read and write the key, I noticed my print routine was not detecting the null terminator in offset (plus) one of a double word array that stores the typed key. Right now I'm simply resetting the terminator, but I thought I'd ask what is happening here. The line in question is marked with ; THIS LINE.

                bits    16
                org     0x7C00
start:          jmp     main

; IMPORTED GET KEY BLOCKING
; IN: NONE
; OUT: AX
bgetkey:
                pusha
                mov     ax, 0
                mov     ah, 10h
                int     16h
                mov     [.buf], ax
                popa
                mov     ax, [.buf]
                ret
                .buf    dw 0
; END IMPORTED FILE

; IMPORTED PRINT STRING TO SCREEN
; IN:   ds->si
; OUT:  NONE
prints:
                mov     ah, 0x0e
                mov     al, [si]
                cmp     al, 0
                jz      print_end
                mov     bh, 0x00
                mov     bl, 0x07
                int     0x10
                inc     si
                jmp     prints
print_end:
                ret
; END IMPORTED FILE

main:
                mov     ax, 0x0000              ; clear ax and
                mov     ds, ax                  ; data segment
                mov     si, welcome
                call    prints
type:
                mov     si, qbuf
                call    bgetkey
                mov     [qbuf], ax
                mov     dword [qbuf + 1], 0      ; THIS LINE
                call    prints
                jmp     type
                welcome db "moose os", 0x0A, 0x0D, 0x00
                newline db 0x0D, 0x0A, 0x00
                qbuf    dw 0, 0

times 0200h - 2 - ($ - $$)  db 0
                dw 0xAA55

This is the output of typing "abcdefg" if I comment out the line in question:

undesired output correct size

This is the desired output with line uncommented:

desired output

Why must I reset qbuf + 1?

1

There are 1 answers

0
Ross Ridge On BEST ANSWER

The problem is that INT 16h AH=00h returns a ASCII character code in AL and an scan code in AH. The mov [qbuf], ax instruction stores both in the buffer, but INT 10h AH=0Eh only prints ASCII characters. It ends up interpreting the scan code you stored in the buffer as an ASCII character and displays it on screen accordingly.

Your mov dword [qbuf + 1], 0 statement fixes this problem by writing 4 zero bytes after the first character in qbuf. This overwrites the scan code stored in the second byte of qbuf. It also sets the remaining two bytes to 0 along with one more byte beyond the end of the 4 byte long qbuf. Anything after qbuf would be overwritten by this statement, but fortunately there's nothing there.

What you should be doing this:

call    bgetkey
mov     [qbuf], al
mov     byte [qbuf + 1], 0  
call    prints

The second MOV instruction isn't necessary in your program as it is now, the byte will already be 0. It's still a good idea though so your code doesn't break if you end up using the qbuf for something else earlier in your program.