这是(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
编辑:此外,当我在文件中的较高位置添加更多数据/代码时,键盘映射会更早地断开,而当我移除较高的数据/代码时,键盘映射则将稍后时断开的。还是根本没有。因此,我知道这与空间限制有关。
答案 0 :(得分:5)
您的代码有多个错误。
a)它没有在已知位置建立堆栈,然后在可能覆盖堆栈的地址(可能在同一地址)上从磁盘加载数据。
b)假定从磁盘加载数据无需检查BIOS是否返回错误即可。
c)它仅加载一个扇区,而无法确定实际大小和“自行调整”;因此随着文件的增长,它将是一个持续的维护工作。这很可能是您的数据“中断”的原因(前512个字节未加载后的所有内容)
d)在定义“ newstart”之前先使用它,然后为时已晚,然后定义“ newstart equa 0x0500”。
e)您假定所有字符都是可打印的。不是(光标移动,功能键...)
还要注意,将字符从QWERTY转换为Dvorak的代码效率极低(遍历所有条目以查找正确的字符,而不是将原始字符用作表的索引,例如movzx eax,al
, mov al,[table+eax]
);并且当前在很多情况下都无法使用(例如,如果用户按下“ Shift + a”或启用了大写锁定)。