我将此代码用于Hello world引导程序。而不是打印出“Hello world \ n”,它只打印出一个'H'并挂起。我已经成功使用了loadb打印出来的消息,但是我无法理解为什么这种方法不会起作用,因为它似乎是等效的。
[ORG 0x7c00]
[BITS 16]
xor ax, ax ;make it zero
mov ds, ax
mov ecx, msg
bios_print:
mov al, [ecx]
add ecx,1
cmp al, 0 ;zero=end of str
je hang ;get out
cmp al,100
jge hang
mov ah, 0x0E
int 0x10
jmp bios_print
hang:
jmp hang
msg db 'Hello World', 13, 10, 0
times 510-($-$$) db 0
db 0x55
db 0xAA
编辑: 我将[BITS 64]更改为[BITS 16]
答案 0 :(得分:4)
您的程序完全以您编码的方式工作。 ASCII中的小写e
表示为65h
,十进制等于101。因此,如果cmp al, 100 / jge hang
(101)位于e
,则执行al
会导致跳转到标签hang
。一切安好。 :)
你的问题的解决方案就是删除那一行,因为我真的没有看到它的任何目的 - 看看你的字符串是如何被\0
终止的,循环将在它结束时结束到了最后。
但有四个额外提示:
cmp
之后执行add
,特别是如果跳转的唯一条件可以由其中一个标志表示。在这种情况下,add ecx, 1 / cmp al, 0 / je hang
可以替换为非常简单的add ecx, 1 / jz hang
。这样可以节省两个字节,这些在bootsector条件下非常有用。pusha
就是这样做的。在调用您自己未编写的任何代码时,保留所有运行时信息通常是一个经验法则(尽管在更“文明”的环境中这可能听起来极端 - 但BIOS和一般实模式代码不是一个)。 mov ecx, msg
只是多余的 - 地址的偏移部分永远不会超过16位。同样适用于add ecx, 1
。在这两种情况下,只需将ecx
替换为cx
。hlt
指令。它使你的CPU血压降得更低,并且在整个地方都没有任何用处。只需在hlt
标签之后和跳转之前添加hang
。