【问题标题】:Is this an overflow, or maybe more keyboard data?这是溢出,还是更多的键盘数据?
【发布时间】:2015-06-18 21:03:25
【问题描述】:

我正在编写一个引导加载程序,它的功能基本上仅限于打印字符串,然后在键入时将键盘字符复制到屏幕上。在编写读取和写入密钥的例程时,我注意到我的打印例程没有检测到存储键入密钥的双字数组之一的偏移量(加)中的空终止符。现在我只是在重置终结器,但我想我会问这里发生了什么。有问题的行标有; 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

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

这是未注释行的所需输出:

为什么我必须重置qbuf + 1

【问题讨论】:

  • 什么是“欢迎”? (第 40 行)。给我错误(未声明)。还有“.buf”(第 13 行)。无法测试您的代码(无法运行)。
  • @JoseManuelAbarcaRodríguez 添加了包含字符串的行。 .buf 有什么问题?
  • 你用的是什么汇编程序?
  • @RossRidge nasm in cygwin

标签: assembly nasm bootloader


【解决方案1】:

问题在于 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 某些东西,您的代码不会中断else 在你程序的前面。

【讨论】:

    猜你喜欢
    • 2015-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多