这是溢出,还是更多的键盘数据?

时间:2015-06-18 21:03:26

标签: assembly nasm bootloader

我正在编写一个bootloader,它的功能基本上只限于打印一个字符串,然后在键入时将键盘字符复制到屏幕上。在编写读取和写入密钥的例程时,我注意到我的打印例程没有检测到偏移(加号)存储键入密钥的双字数组中的空终止符。现在我只是重置终结器,但我想我会问这里发生了什么。有问题的行标有Setup::createYAMLMetadataConfiguration

; THIS LINE

如果我注释掉有问题的行,这是输入“abcdefg”的输出:

undesired output correct size

这是取消注释行的所需输出:

desired output

为什么我必须重置 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

1 个答案:

答案 0 :(得分:2)

问题是INT 16h AH = 00h返回AL中的ASCII字符代码和AH中的扫描代码。 mov [qbuf], ax指令存储在缓冲区中,但INT 10h AH = 0Eh仅打印ASCII字符。它最终将您存储在缓冲区中的扫描代码解释为ASCII字符,并相应地在屏幕上显示。

您的mov dword [qbuf + 1], 0语句通过在qbuf中的第一个字符后写入4个零字节来解决此问题。这会覆盖存储在qbuf的第二个字节中的扫描代码。它还将剩余的两个字节设置为0,并在4字节长qbuf的末尾之外再设置一个字节。 qbuf之后的任何内容都会被此声明覆盖,但幸运的是那里没有任何内容。

你应该做什么:

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

现在你的程序中没有必要使用第二条MOV指令,字节已经是0.虽然如果最终使用qbuf你的代码不会破坏,但仍然是个好主意。在你的程序中更早的其他内容。