(程序集x86实模式)程序结束时数据“中断”了吗?

时间:2018-09-23 06:44:19

标签: assembly x86 operating-system nasm real-mode

这是(nasm x86 real mode) How to write/read strings in boot-loaded sector?的后续行动。

我正在为NASM中的x86实模式开发玩具OS。 512B引导扇区将其余代码加载到另一个扇区。问题是程序结束时我似乎空间不足。

这是源文件的开头:

;;; nasm -f bin -o boot.bin os.asm
;;; qemu-system-x86_64 boot.bin

    bits 16

    section boot, vstart=0x0000

    ;; Load next sector.
    ;; adapted from:
    ;; https://blog.benjojo.co.uk/post/interactive-x86-bootloader-tutorial
    mov ah, 0x02
    mov al, 1   
    mov ch, 0    
    mov cl, 2    
    mov dh, 0   
    mov bx, newsector 
    mov es, bx  
    xor bx, bx
    int 0x13
    jmp newsector:0

    newsector equ 0x0500

    times 510-($-$$) db 0
    db 0x55
    db 0xaa

    section os, vstart=0x0000
    mov ax, newsector
    mov ds, ax

这是源文件的末尾,我在其中存储数据。有一个键盘映射,可根据Dvorak键盘布局转换输入。但是该程序似乎在fu之后被“切断”了。

    input times 16 db 0
    repl_prompt times 16 db 0

    dvorak db 1

dvorak_keymap:
    db "aa"
    db "nb"
    db "ic"
    db "hd"
    db "de"
    db "yf"
    db "ug"
    db "jh"
    db "gi"
    db "cj"
    db "vk"
    db "pl"
    db "mm"
    db "ln"
    db "so"
    db "rp"
    db "xq"
    db "or"
    db ";s"
    db "kt"
    db "fu"
    db ".v"     ; FIXME: gets cut off here
    db ",w"
    db "bx"
    db "ty"
    db "/z"
    db 0

因此,在启动操作系统时,可以在Dvorak中键入键a-u,但不能键入v-z。此外,在print字符串上调用程序的dvorak_keymap函数可确认该字符串在fu之后终止。

但更重要的是,这表明我的程序空间不足,因此无法再添加任何数据或代码。我不能达到1 MB的内存限制,因为源文件只有282 sloc。

我猜测这与我如何加载扇区有关?我是汇编语言和底层编程的新手,所以将非常感谢您的帮助。

来源:https://github.com/jtherrmann/os/blob/master/os.asm

原始:https://raw.githubusercontent.com/jtherrmann/os/master/os.asm

编辑:此外,当我在文件中的较高位置添加更多数据/代码时,键盘映射会更早地断开,而当我移除较高的数据/代码时,键盘映射则将稍后时断开的。还是根本没有。因此,我知道这与空间限制有关。

1 个答案:

答案 0 :(得分:5)

您的代码有多个错误。

a)它没有在已知位置建立堆栈,然后在可能覆盖堆栈的地址(可能在同一地址)上从磁盘加载数据。

b)假定从磁盘加载数据无需检查BIOS是否返回错误即可。

c)它仅加载一个扇区,而无法确定实际大小和“自行调整”;因此随着文件的增长,它将是一个持续的维护工作。这很可能是您的数据“中断”的原因(前512个字节未加载后的所有内容)

d)在定义“ newstart”之前先使用它,然后为时已晚,然后定义“ newstart equa 0x0500”。

e)您假定所有字符都是可打印的。不是(光标移动,功能键...)

还要注意,将字符从QWERTY转换为Dvorak的代码效率极低(遍历所有条目以查找正确的字符,而不是将原始字符用作表的索引,例如movzx eax,almov al,[table+eax]);并且当前在很多情况下都无法使用(例如,如果用户按下“ Shift + a”或启用了大写锁定)。