2017-08-06 89 views
0

彙編程序使用標籤的,我是學在OS發展book by Nick Blundell。它在第3章的引導扇區編程的例子(16位實模式),如下圖所示:內存引用,並通過BIOS加載到內存中引導扇區

; 
; 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 

我的結果是這樣的:

enter image description here

這暗示我QEMU BIOS中打印「X 「只有第三次嘗試。我沒有修改這本書的例子,我想知道我錯過了什麼。


UPDATE的我的二進制碼

對象轉儲表明,對於 「X」,即0x58十六進制的ASCII代碼爲存儲器地址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 ] 

現在輸出爲預期:

enter image description here

回答

4

最後一個是用一個固定的地址。由於您的代碼如何組裝,X可能不會在該地址結束。你可以要求使用-l選項的列表文件nasm,看看自己。在這裏,我得到:

23         the_secret : 
24 0000001D 58        db "X" 

你可以看到它的地址0x1d0x1e。本書的彙編程序可能使用前面的jmp $的3個字節跳轉,因此有1個字節的差異。您可以將其更改爲jmp near $,然後代碼將按預期工作。您當然也可以修復地址。

PS:這是一個壞主意離開ds未初始化的,你永遠不知道BIOS如何設置。常見的可能性是0x7c00這代碼只在後一種情況下工作。萬一ds=0x7c0然後僅第二X出現。