我使用 BIOS 整數撰寫了一個 16 位列印函式,但它無限列印相同的亂碼,所以我進入 Bochs 除錯器并檢查函式中的每條指令,并注意到mov dl,[bx]我撰寫的指令已被mov dl,ds:[edi]機器代碼替換67 8A 17。
我知道添加的 ds 段選擇器是正常的,但為什么bx被替換為di?
以下是該print_str函式的完整代碼:
;BX = ptr to null terminaetd string
print_str:
pusha
next_char:
mov dl,[bx]
test dl,dl
jz print_str_return
mov ah,0x0E
mov al,dl
int 0x10
inc bx
jmp next_char
print_str_return:
popa
ret
這只發生在我呼叫函式時;如果我將函式體復制到call指令所在的位置,則匯編器不會替換bx為edi. 我對此感到非常困惑。
boot.asm 的代碼如下所示:
[extern kernel_entry]
[bits 16]
mov [BOOT_DRIVE], dl
mov ax,0
mov ds,ax
mov es,ax
mov ss,ax
;Set up a temporary stack (~65kB)
mov ax,0xFFFF
mov sp,ax
mov bp,sp
...
mov bx,msg
call print_str
...
%include "printer.asm"
msg: db "test string",0
...
這是根據 bochs 除錯器的指令的樣子。

di保存亂碼值,同時bx保存字串的真實地址,但匯編器決定替換bx為edi?
uj5u.com熱心網友回復:
我解決了這個問題。
該[bits 32]指令是罪魁禍首。匯編器顯然將我的print_str函式編碼為 32 位指令(因為我所有的包含都在檔案的末尾,并且指令就在它們的正上方)。我所做的只是在包含之前但在32 位保護模式代碼之后重新添加[bits 16]指令。這是代碼:
cli ;Disable interrupts
lgdt [gdtr_data] ;Load the GDT
;Set first bit (protected mode enable) in control register 0
mov eax,cr0
or eax,0x1
mov cr0,eax
jmp CODE_SEGMENT:post_flush
post_flush:
;-----------------------------------------------32 bit Protected mode-----------------------------------------------
[bits 32]
;Set up a new kernel stack (~630 kB)
mov eax,0x9FC00
mov ebp,eax
mov esp,ebp
call kernel_entry ;Jump to kernel, 'void kernel_entry()' is defined on src/MKernel/entry.c
jmp $
[bits 16]
%include "printer.asm"
...
從評論所指出的來看,x86 對 16 位指令mov dl,ds:[bx]的編碼方式似乎與對 32 位指令的編碼方式相同,mov dl,ds:[edi]這正是我的問題。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/492922.html
上一篇:管理通用暫存器AVR
