x86程序集OS hello world无法正常工作

时间:2013-08-31 12:47:51

标签: assembly x86 nasm

我制作了这个代码,这应该是简单的操作系统,应该打印" 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"是那个文件。 有人知道解决方案吗?

3 个答案:

答案 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”指令。