2

我做了这段代码,这应该是简单的操作系统,应该打印“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 

我在 NASM 上组装了它。当我在 QEMU 上运行它时,它会打印一个奇怪的字符和“S”。

我使用这些参数“qemu-system-x86_64 ost.bin”运行 QEMU,其中“ost.bin”是那个文件。有人知道解决方案吗?

4

3 回答 3

2

您必须在代码开头插入“ org 7c00h ”。

而且,你必须在打印后停止程序,否则它会再次陷入 printstr 程序。

也许是这样的:

sleep: hlt 
       jmp sleep
于 2013-08-31T12:50:32.857 回答
1

您的代码中有几个问题:

bits 16
 mov bx, msg

msg现在仅包含您的消息与输出二进制文件开头的偏移量。您可以通过添加或设置程序原点(在内存中开始)0x7c00来解决此问题。msgORG 0x7c00

  call printstr
printstr:
  mov al,byte[bx]

BX不是索引字符串字符的好寄存器,因为它包含颜色(低字节)和页面(高字节)信息。

  mov ah,0Eh
  int 10h

您不必每次打印字符时都设置AH为。0x0E它可以在代码的开头完成。

  inc bx
  cmp byte[bx], 0

在这种循环中,您应该首先检查值,然后对其进行处理。如果 character onBX+0等于 ,你会怎么做0?你会错过这个事实,这会导致错误的输出甚至无限循环。

  je end
  jmp printstr

这肯定会导致无限循环,因为您已经处于该过程中。

end:
  jmp end

首选语法是jmp $(其中美元符号表示“此处”)。

msg: db "Hello world!",0
times 510-($-$$) db 0
dw 0xaa55 
于 2013-08-31T13:02:27.853 回答
0

主要问题似乎是段寄存器(DS 和 ES)未初始化。

不需要“org 7C00h”;程序也可以从地址 100h(DOS .COM 文件的理想地址)或 0h 开始。根据起始地址,段寄存器必须初始化为 7C0h (org 0h)、7B0H (org 100h) 或 0 (org 7C00h)。

最后的“jmp sleep”指令就足够了;绝对不需要“HLT”指令。

于 2013-08-31T15:00:30.557 回答