Assembly 内存引用和使用BIOS加载到内存作为引导扇区的汇编程序中的标签

Assembly 内存引用和使用BIOS加载到内存作为引导扇区的汇编程序中的标签,assembly,x86,nasm,bios,Assembly,X86,Nasm,Bios,我正在学习一门关于操作系统开发的课程。第三章有一个例子。引导扇区编程(16位实模式),如下所示: ; ; A simple boot sector program that demonstrates addressing. ; mov ah, 0x0e ; int 10/ ah = 0eh -> scrolling teletype BIOS routine ; First attempt mov al, the_secret int 0x10 ; Does this print an

我正在学习一门关于操作系统开发的课程。第三章有一个例子。引导扇区编程(16位实模式),如下所示:

;
; A simple boot sector program that demonstrates addressing.
;
mov ah, 0x0e ; int 10/ ah = 0eh -> scrolling teletype BIOS routine

; First attempt
mov al, the_secret
int 0x10 ; Does this print an X?

; Second attempt
mov al, [the_secret]
int 0x10 ; Does this print an X?

; Third attempt
mov bx, the_secret
add bx, 0x7c00
mov al, [bx]
int 0x10 ; Does this print an X?

; Fourth attempt
mov al, [0x7c1e ]
int 0x10 ; Does this print an X?

jmp $ ; Jump forever.

the_secret :
        db "X" 

; Padding and magic BIOS number.
times 510 -( $ - $$ ) db 0

dw 0xaa55
书中提到:

如果我们运行这个程序,我们会看到只有后两次打印成功 一个“X”

好吧,这不是我得到的结果:

$ nasm BOOK_EXAMPLE.asm -f bin -o BOOK_EXAMPLE.bin
$ qemu-system-i386 BOOK_EXAMPLE.bin
我的结果是:

这意味着我的QEMU BIOS仅在第三次尝试时打印“X”。我没有修改书中的示例,我想知道我遗漏了什么


更新

二进制代码的对象转储显示“X”的十六进制ASCII代码,即
0x58
位于内存地址
0x7c00
+
0x001d
=
0x7c1d

$ od -t x1 -A x BOOK_EXAMPLE.bin 
000000 b4 0e b0 1d cd 10 a0 1d 00 cd 10 bb 1d 00 81 c3
000010 00 7c 8a 07 cd 10 a0 1e 7c cd 10 eb fe 58 00 00
000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
*
0001f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa
000200
因此,我将一个代码行替换为以下代码行:

mov al, [0x7c1d ]
现在输出如预期:


最后一个使用的是固定地址。由于您的代码是如何组装的,
X
可能不会出现在该地址。您可以使用
-l
选项向
nasm
请求一个列表文件,然后自己查看。在这里,我得到:

23                                  the_secret :
24 0000001D 58                              db "X" 
您可以看到它的地址
0x1d
而不是
0x1e
。本书的汇编程序可能对前面的
jmp$
使用了3字节的跳转,因此产生了1字节的差异。您可以将其更改为$附近的
jmp,然后代码将按预期工作。当然,你也可以确定地址


PS:不初始化ds是个坏主意,你永远不知道bios是如何设置的。常见的可能性是
0x7c0
0
,此代码仅适用于后一种情况。如果
ds=0x7c0
则只显示第二个
X

最后一个使用的是固定地址。由于您的代码是如何组装的,
X
可能不会出现在该地址。您可以使用
-l
选项向
nasm
请求一个列表文件,然后自己查看。在这里,我得到:

23                                  the_secret :
24 0000001D 58                              db "X" 
您可以看到它的地址
0x1d
而不是
0x1e
。本书的汇编程序可能对前面的
jmp$
使用了3字节的跳转,因此产生了1字节的差异。您可以将其更改为$
附近的
jmp,然后代码将按预期工作。当然,你也可以确定地址

PS:不初始化ds是个坏主意,你永远不知道bios是如何设置的。常见的可能性是
0x7c0
0
,此代码仅适用于后一种情况。如果
ds=0x7c0
则只显示第二个
X