[英]How can we use `e[]x` in 16-bit but not `r[]x` in 32-bit
因此,在匯編中,如何在16位實模式下使用e[]x
卻不能在32位模式下使用r[]x
? 例如:
BITS 16
mov bx, 1
mov eax, 2
將在IDA中正確組裝和拆卸(在16位模式下)。 它可以像我之前拆解Win2k引導加載程序並找到eax
引用一樣工作。
但是,為什么即使在保護模式下的64位處理器上也無法訪問r[]x
呢?
這樣做的原因是64位模式在一個特定位置更改了指令解碼-即,啟用用於指示操作數大小為64位的前綴字節/將寄存器寬度擴展到64位/將寄存器用法擴展到“新” R8
.. R15
寄存器。 它們不同於“備用大小前綴”( 0x66
),后者對x86是通用的(與CPU工作模式無關),並且在16位模式下將操作數/寄存器的大小從16bit更改為32bit,反之則從32bit更改為16bit。在32位模式下
所謂的REX
前綴編碼為0x40
.. 0x4f
,並且僅當CPU在64位模式下運行時才作為前綴有效。 為什么會這樣 ? 嗯-就像說的,改變了指令解碼,這些操作碼實際上映射到經典x86中的inc <reg>
/ dec <reg>
一字節版本。
這是可能的,因為在16位/ 32位指令集的模糊的- inc EAX
可以是 0x40
或 0xff 0xc0
。 在64位模式下,指令解碼器為此僅接受0xff 0xc0
。 另一方面,如所示, 0x40
成為REX
前綴之一。
因此-這些64位操作數大小前綴在16bit / 32bit模式下不存在 (它們是inc
/ dec
操作,然后...),因此16bit / 32bit x86代碼無法聲明“我想執行64bit” op”。
例如,以下是一些具有不同操作數大小的指令的匯編/操作碼:
64bit 32bit option 1 32bit option 2 instruction ============================================================= fe c8 fe c8 -- dec al 66 ff c8 66 ff c8 66 48 dec ax ff c8 ff c8 48 dec eax 48 ff c8 -- -- dec rax
如您所見,64位不知道dec eax
單字節版本,但它知道0x48
作為指令前綴中的“(使它成為64位op”)(幾種)之一。
好吧,如果您使用的是80286,它將無法正常工作! 您使用的計算機是32位CPU,它同時具有16位和32位寄存器,但沒有64位寄存器。 它也可以在64位cpu上工作。
通過設計和CPU設計,您不能在非64位模式下訪問64位寄存器。
通過設計,您也可以以16位模式訪問32位寄存器。 通過使用稱為operand size prefix
和address size prefix
的特殊指令前綴來執行此operand size prefix
。 在非64位模式下,沒有特殊的指令前綴可以到達64位寄存器。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.