2017-04-02 55 views
-2

我正在爲MBR(實模式)編寫一些程序集。我知道在實模式下,你不能使用32位寄存器,只能使用16位寄存器。在實模式和解引用中的32位寄存器

我寫了這個代碼,它依賴於print_char函數。

mov ecx, MSG 
write: 
    mov al, [ecx] 
    cmp al, 0x0 
    je end_print 
    call print_char 
    inc cx 
    jmp write 
end_print: 
    ret 
MSG: db 'Hi!', 0xd, 0xa, 0x0 

此代碼不能編譯由於原因:

error: invalid effective address 

我用

nasm -f bin -o out src.s 

當我改變寄存器名稱ecx,該代碼開始編譯,令人驚訝的是,工程。

爲什麼我的代碼使用32位寄存器工作在實模式,爲什麼使用16位寄存器不是?

+2

您可以在32位cpu上使用32位寄存器,實模式還是不使用。但是如果你使用16位尋址,你必須使用有效的模式,'[cx]'不是一個。 – Jester

+0

爲什麼降價? – marmistrz

+0

我沒有倒下,但我的猜測是他們覺得「它沒有顯示任何研究成果」。您可以自己查看intel手冊中的尋址模式,特別是_「地址大小覆蓋前綴(67H)允許程序在16位和32位尋址之間切換。任何一種大小都可以是默認值;前綴選擇非默認大小。「_ – Jester

回答

1

x86 ISA支持多種尋址模式。有兩組尋址模式,一組用於16位模式,另一組用於32位模式。

在32位模式下,可以對任何寄存器和三部分SIB尋址使用索引尋址。

在16位方式中,僅以下尋址模式存在(每個具有可選的位移):

BX + disp 
BX + SI + disp 
BX + DI + disp 
BP + disp 
BP + SI + disp 
BP + DI + disp 
SI + disp 
DI + disp 
disp 

注意如何cx不可用作爲索引寄存器。

你能做些什麼來解決這個問題是在16位模式下使用32位尋址模式。這是通過將ecx指定爲索引寄存器來完成的。

+0

爲什麼我可以在16位模式下使用32位尋址?如果處理器對其本身施加了額外的16位約束,則不應該允許它。 – marmistrz

+1

沒有理由限制這一點。它向後兼容,只是給你更多的選擇。請注意,您可以同樣在32位模式下使用16位尋址,在64位模式下使用32位尋址(但只有最後一個通常有用)。 – Jester

+1

@marmistrz基本上,32位模式的設計使得16位程序可以根據需要使用32位指令。這是通過兩個前綴66和67完成的,它們切換數據並尋址到32位模式。在32位模式下,這些前綴的含義簡單相反。 – fuz

相關問題