【发布时间】:2021-09-18 04:40:06
【问题描述】:
这是一个关于 x86-64 (AMD64) 架构中操作数大小覆盖前缀的问题。
这是一堆汇编指令(nasm)及其编码; new 我的意思是 r8, ..., r15 寄存器:
67: address-size override prefix
|
| 4x: operand-size override prefix
| |
; Assembler ; | Dst operand | Src operand | -- --
mov eax,ecx ; | 32-bit | 32-bit | 89 C8 |
mov r8d,ecx ; | 32-bit new | 32-bit | 41 89 C8 |
mov eax,r9d ; | 32-bit | 32-bit new | 44 89 C8 |
mov r8d,r9d ; | 32-bit new | 32-bit new | 45 89 C8 |
mov rax,rcx ; | 64-bit | 64-bit | 48 89 C8 |
mov r8,rcx ; | 64-bit new | 64-bit | 49 89 C8 |
mov rax,r9 ; | 64-bit | 64-bit new | 4C 89 C8 |
mov r8,r9 ; | 64-bit new | 64-bit new | 4D 89 C8 |
lea eax,[ecx] ; | 32-bit | 32-bit | 67 8D 01 |
lea r8d,[ecx] ; | 32-bit new | 32-bit | 67 44 8D 01 |
lea eax,[r9d] ; | 32-bit | 32-bit new | 67 41 8D 01 |
lea r8d,[r9d] ; | 32-bit new | 32-bit new | 67 45 8D 01 |
lea rax,[rcx] ; | 64-bit | 64-bit | 48 8D 01 |
lea r8,[rcx] ; | 64-bit new | 64-bit | 4C 8D 01 |
lea rax,[r9] ; | 64-bit | 64-bit new | 49 8D 01 |
lea r8,[r9] ; | 64-bit new | 64-bit new | 4D 8D 01 |
push rax ; | | 64-bit | 50 |
push r8 ; | | 64-bit new | 41 50 |
通过研究这些以及与其他寄存器相同的指令,我推断出以下内容。 “旧”和“新”寄存器之间存在配对。并非详尽无遗:
AX <--> R8
CX <--> R9
DX <--> R10
BX <--> R11
BP <--> R13
忽略大小前缀,指令字节不是指特定的寄存器,而是指寄存器对。例如:字节 89 C8 表示一条 mov 指令从源(ecx、rcx、r9d 或 r9)到目标(eax、rax、r8d 或 r8)。鉴于操作数必须同时为 32 位或 64 位宽,因此有八种合法的可能组合。操作数大小覆盖前缀(或不存在)指示这些组合中的哪一个是预期的组合。例如,如果前缀存在且为 44,则源操作数必须是 32 位新寄存器(在此示例中,然后折叠为 r9d),目标必须是 32 位旧寄存器(此处为 eax 信号)。
我可能没有完全正确,但我想我明白了它的要点。这样看来,操作数大小覆盖前缀所覆盖的事实是,如果没有它们,指令将使用 32 位“旧”操作数。
但可以肯定的是,有一些事情让我无法理解,否则:谈论“具有 64 位默认操作数大小的 x86-64 版本”(如 here)有什么意义?
或者有没有办法在 64 位机器上运行,将默认操作数大小设置为 32 或 64,如果是这样,并且如果我的程序适当地设置了机器,我会看到不同的编码?
另外:什么时候会使用 66H 操作数大小的覆盖前缀?
【问题讨论】:
-
查看英特尔软件开发手册。然后解释了前缀的编码和含义。我以后可能会写一个真正的答案。
-
40h到4Fh前缀称为 REX 前缀。它们可以指示 64 位操作数大小。它们还可以指示将高 8 个寄存器之一用于源或目标。我相信这些选项的任何组合都是可能的。 -
66 前缀将操作数大小更改为 16 位。
-
在机器码中是,大多数指令默认为 32 位,堆栈和跳转/调用指令默认为 64 位。在汇编源代码中,没有默认值,它必须由寄存器隐含或明确指定。 (除了一些默认为 push/pop 的汇编程序。)请注意,16 位 AX 对应于 16 位 R8W,而 RAX 和 R8 是由 REX 前缀区分的对。
-
@ecm 具体来说,REX 前缀编码四位状态(一位用于操作数大小,三位用于高位寄存器)。仅存在 REX 前缀就额外编码了您想要的
sil、dil、spl和bpl,而不是ah、ch、dh和bh。
标签: assembly x86-64 machine-code prefixes