Ryzen 支持monitorx指令,如 cpuid 標志所示。不幸的是,Visual Studio masm 匯編器似乎不喜歡這些說明,并且關于如何使用它們的在線檔案很少。
以下代碼(非常基于 AMD 自己的檔案)報告錯誤 A2070 "invalid instruction operands:
push rbx
mov eax, 5844h
mov ecx, 0
mov edx, 0
monitorx eax, ecx, edx
pop rbx
ret
我知道這段代碼不是很有用,但它不應該拋出構建時錯誤,那么有什么關系呢?
uj5u.com熱心網友回復:
問題是 eax、ecx 和 edx 是 32 位暫存器,但它是在 64 位模式下組裝的。因為第一個運算元是指標大小,所以它必須是 64 位。以下代碼適用于 64 位程式:
push rbx
mov eax, 5844h
mov ecx, 0
mov edx, 0
monitorx rax, rcx, rdx
pop rbx
ret
uj5u.com熱心網友回復:
在機器代碼中,運算元是隱式的。在匯編語法中,plainmonitorx適用于大多數匯編程式。可以指定運算元來記錄指令,或者在某些匯編程式中指定對地址大小的覆寫。
AMD 的手冊明確指出 ECX 和 EDX 是 32 位運算元。(他們說沒有定義任何提示或擴展,因此 ECX 必須為 0 否則 #GP,并且 EDX 被當前 CPU 忽略。)
對于地址運算元,他們將其記錄為 rAX,我認為這意味著它可以是 EAX 或 RAX。在偽代碼示例中,他們使用MONITORX EAX, ECX, EDX,但 32 位 EAX 表示這是一個 32 位模式示例。
這是他們的第 3 卷手冊,2021 年 11 月,修訂版 3.33,最新鏈接來自https://developer.amd.com/resources/developer-guides-manuals/。
NASM 2.15.05(monitorx在2.12.01版本中添加了支持)
可以指定或省略運算元串列。如果指定,第一個運算元必須是 EAX 或 RAX,接下來的兩個必須是 ECX 和 EDX。(指定 RCX 或 RDX 是錯誤的)。
但是 NASM 不會從使用 EAX 推斷 64 位模式下的 32 位地址大小。
可以使用 NASM 前綴指定段覆寫。
示例串列來自nasm -l/dev/stdout -felf64 foo.asm:
1 00000000 0F01FA monitorx
2 00000003 0F01FA monitorx rax, ecx, edx
3 00000006 0F01FA monitorx eax, ecx, edx ; address-size override not inferred from EAX
4 00000009 670F01FA a32 monitorx ; address-size prefix, NASM style
5 0000000D 640F01FA fs monitorx rax, ecx, edx ; segment override works, too
上一篇:mwaitx指令不阻塞ndisasm -b64將其反匯編為monitorx,fs monitorx或a32 monitorx不列出隱式運算元。GNU Binutilsobjdump在語法模式下是相同的-Mintel,但在 AT&T 模式下列出運算元。(向后,使用%raxor
