我制作了这个代码,这应该是简单的操作系统,应该打印" Hello world!"。
bits 16
mov bx,msg
call printstr
printstr:
mov al,byte[bx]
mov ah,0Eh
int 10h
inc bx
cmp byte[bx],0
je end
jmp printstr
end:
jmp end
msg: db "Hello world!",0
times 510-($-$$) db 0
dw 0xaa55
bits 16
mov bx,msg
call printstr
printstr:
mov al,byte[bx]
mov ah,0Eh
int 10h
inc bx
cmp byte[bx],0
je end
jmp printstr
end:
jmp end
msg: db "Hello world!",0
times 510-($-$$) db 0
dw 0xaa55
我在NASM上组装了这个。
当我在QEMU上运行它时,会打印出一个奇怪的角色,并且' S'。
我用这些参数运行了QEMU " qemu-system-x86_64 ost.bin"在哪里" ost.bin"是那个文件。 有人知道解决方案吗?
答案 0 :(得分:2)
您必须在代码的开头插入“ org 7c00h ”。
而且,你必须在打印后停止程序,否则它将再次落入printtr程序。
可能是这样的:
sleep: hlt
jmp sleep
答案 1 :(得分:1)
您的代码中存在几个问题:
bits 16
mov bx, msg
msg
现在只包含从输出二进制文件开始的消息偏移量。您可以通过将0x7c00
添加到msg
或设置程序源(在内存中启动,ORG 0x7c00
)来解决此问题。
call printstr
printstr:
mov al,byte[bx]
BX
不是索引串行字符的好寄存器,因为它包含颜色(低字节)和页面(高字节)信息。
mov ah,0Eh
int 10h
每次打印字符时都不必将AH
设置为0x0E
。它可以在代码的开头完成。
inc bx
cmp byte[bx], 0
在这种循环中,您应首先检查值,然后处理它。如果BX+0
上的字符等于0
,您会怎么做?你会错过这个事实,这会导致输出错误甚至无限循环。
je end
jmp printstr
这肯定会导致无限循环,因为你已经在那个程序中。
end:
jmp end
首选语法为jmp $
(其中美元符号表示“此处”)。
msg: db "Hello world!",0
times 510-($-$$) db 0
dw 0xaa55
答案 2 :(得分:0)
主要问题似乎是段寄存器(DS和ES)未初始化。
不需要“org 7C00h”;程序也可以从地址100h(DOS .COM文件的理想选择)或0h开始。根据起始地址,段寄存器必须初始化为7C0h(org 0h),7B0H(org 100h)或0(org 7C00h)。
最后的“jmp sleep”指令就足够了;绝对不需要“HLT”指令。