- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
GAS 为以下指令提供以下编码:
push rbp # 0x55
push rbx # 0x53
push r12 # 0x41 0x54
push r13 # 0x41 0x55
来自AMD64 spec (第 313 页):
PUSH reg64 50 +rq
Push the contexts of a 64-bit register onto the stack.
由于 rbp
和 rbx
的偏移量分别为 5 和 3,因此前两种编码是有意义的。不过,我不明白最后两种编码是怎么回事。
据我所知,0x40-0x4f
是一个 REX 前缀,0x41
具有 REX.B
位集(它是对MODRM.rm
或 SIB.base
的 MSB,根据此 external reference )。规范提到要访问所有 16 个 GPR,您需要使用 REX,但尚不清楚截止点在哪里。
通过查阅 MODRM 和 SIB 的文档,我认为没有使用 SIB,因为它的目的是使用基址+偏移寄存器进行索引(尽管说实话,我无法真正告诉你如何区分 MODRM 和SIB 仅给出编码)。
所以,我怀疑这里使用了 MODRM。目前仅考虑 push r12
(0x41 0x54
)(并注意 r12
具有偏移量 12
),我们有:
+----------------+--------------------+
| 0x41 | 0x54 |
+----------------+--------------------+
| REX | MODRM |
+--------+-------+-----+--------+-----+
| Prefix | WRXB | mod | reg | rm |
| 0100 | 0001 | 01 | 01 0 | 100 |
+--------+-------+-----+--------+-----+
REX.B + MODRM.rm = 0b1100 = 12
因此这表明这是源寄存器(r12
= 偏移量 12)。如果忽略 external (unofficial) reference 中的所有表,REX.R + MODRM.mod + MODRM.reg = 0b00101 = 5
,这是推送指令基0x50
的第一个半字节。
所以,我想我已经向后工作了,但我不明白如何得到像 0x41 0x54
这样的编码。来自 AMD reference ,图 1-10(第 54 页)有一个脚注,如果 MODRM.mod = 01 或 10
,则该字节“包括由指令位移字段指定的偏移量”。这也许暗示了为什么我们有指令偏移量REX.R + MODRM.mod + MODRM.reg = 0b00101 = 5
。但是,为什么 MODRM.mod
部分是指令偏移量呢?如果必须包含它,则采用此偏移形式的指令仅限于前缀 0b01
或 0x10
。这不可能是正确的,对吧?
tl;博士
push
等指令?push rbp
或 push rbx
那样对 push r12
执行 0x50 + 12 吗?)<MODRM.mod
? (或者这是正确的吗?)pop
等类似指令是否一致? (我怎么知道哪些指令支持这个?它适用于所有具有 XX +xx
形式的操作码的指令吗?)最佳答案
这里显然没有 ModRM 字节,因为整个指令都是一个字节。如果没有操作码字节,就不可能有 ModRM。
push reg
/pop reg
短格式将3位寄存器代码嵌入到操作码字节中。这就是50 + rq
方法。 (与使用 ModRM 的 FF /6
push r/m64
编码不同;您可以用它来编码寄存器操作数以使指令更长,但通常您只会将其用于 push qword [rdi]
或其他东西)。
它与 16/32 位格式相同,这就是为什么 x86-64 需要一个额外的位(来自 REX 前缀)来编码具有 4 位代码的"new"/上位寄存器之一设置了前导位。
OSdev省略了这个案例,只提到了ModRM.rm
和SIB.base
.
3.1.1.1 Opcode Column in the Instruction Summary Table (Instructions without VEX Prefix)
...
+rb, +rw, +rd, +ro — Indicated the lower 3 bits of the opcode byte is used to encode the register operand without a modR/M byte. The instruction lists the corresponding hexadecimal value of the opcode byte with low 3 bits as 000b. In non-64-bit mode, a register code, from 0 through 7, is added to the hexadecimal value of the opcode byte. In 64-bit mode, indicates the four bit field of REX.b and opcode[2:0] field encodes the register operand of the instruction. “+ro” is applicable only in 64-bit mode. See Table 3-1 for the codes.
表 3-1 使用与 ModRM 和 SIB 中的寄存器编号相同的编码方案,这并不奇怪,但英特尔全力以赴,拥有所有操作数大小的所有整数寄存器的完整表。包括AH/BH/CH/DH,因为mov ah, 1
可以使用 2 字节短格式。
我从“四字寄存器(仅限 64 位模式)”列中摘录了相关行:
From Intel's Table 3-1. Register Codes Associated With +rb, +rw, +rd, +ro
reg REX.B Reg Field
RBX None 3
RBP None 5
R12 Yes 4
R13 Yes 5
有趣的事实:在英特尔的手册中,他们实际上使用 50 + rd
而不是50 + ro
对于 PUSH r64
,与 push r32
相同在 32 位模式下。 https://www.felixcloutier.com/x86/push .
Is this consistent for similar instructions like pop? (And how do I know which instructions support this? Does it work for all instructions that have opcodes of the form XX +xx?)
是的。 push/pop reg
, mov reg,imm
,和xchg eax, r32
/xchg rax, r64
全部使用相同的编码,具有 3 个操作码位来对寄存器进行编码。
如果我们能拥有这 8 个就好了 xchg
操作码返回一些更有用的东西(比如 64 位模式下更紧凑的 VEX 或 EVEX 前缀),但是当 AMD 对 AMD64 采取保守态度时,这艘船航行了,主要保持机器代码尽可能与 32 位模式相似。他们确实收回了0x4?
inc/dec reg
不过,操作码用作 REX 前缀。
关于assembly - PUSH 的 Intel REX 编码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54519462/
我是Intel pin工具的新手,最近开始研究pin工具。在教程中,描述了pin工具的模式: Sometimes, however, it can be useful to look at diffe
我是Intel pin工具的新手,最近开始研究pin工具。在教程中,描述了pin工具的模式: Sometimes, however, it can be useful to look at diffe
我得到了这份工作:1。产生一个正弦信号。2。使用 FFT 构建其频谱。首先,我为 visual studio 2010 安装了 Intel Parallel Studio XE 2011。在 vs 2
看起来 Intel 提供了许多 OpenCL 实现。 ArchWiki描述 OpenCL 实现。它说 beignet 和 intel-opencl 已弃用。那么,intel-compute-runti
我正在尝试通过阅读 Intel Intrinsics Guide 来开始使用 AVX512 内在函数但到目前为止我发现它没有定义命名数据类型或用于解释的伪代码语法。没有这样的定义,所谓的指南对我起码没
关闭。这个问题是opinion-based 。目前不接受答案。 想要改进这个问题吗?更新问题,以便 editing this post 可以用事实和引文来回答它。 . 已关闭 4 年前。 Improv
在 Android SDK 管理器中,我可以看到 3 种类型的 Intel Atom 图像。有人可以解释“Intel Atom Image”、“Google APIs Intel Atom Image
我写了这个 pintool: #include "pin.H" #include #include VOID Instruction(INS ins, VOID *v) { cou
我正在尝试了解 _mm256_permute2f128_ps() 的作用,但无法完全理解 intel's code-example . DEFINE SELECT4(src1, src2, contr
我正在开发一个性能关键应用程序,该应用程序必须移植到仅支持 MMX、SSE、SSE2 和 SSE3 的英特尔凌动处理器中。我以前的应用程序支持 SSSE3 和 AVX,现在我想将其降级为 Intel
我有最新版本的 Intel Pin 3.0 版本 76887。 我有一个支持 MPX 的玩具示例: #include int g[10]; int main(int argc, char **arg
我想研究和比较elf、SPARC和PA-RISC的可执行文件结构。 为了进行研究,我想在 Intel 机器 (Core2Duo) 上安装 OpenSolaris。 但我有一个基本的疑问,它会起作用吗?
我尝试使用 g++ 用 intel mkl 11.1 进行编译: g++ -m32 test.c -lmkl_intel -lmkl_intel_thread -lmkl_core -liomp5 -
我正在按照以下说明进行操作: https://software.intel.com/en-us/articles/building-boost-with-intel-c-compiler-150 Co
我正在尝试在我的 C 程序中使用内联汇编程序 __asm,使用 Intel 语法而不是 AT&T 语法。我正在使用 gcc -S -masm=intel test.c 进行编译但它给出了错误。下面是我
我是 OpenCL 的新手,目前对其性能有一些疑问。 我有 Intel(R) Core(TM) i5-4460 CPU @ 3.20GHz + ubuntu + Beignet(Intel 开源 op
我在/ex 文件夹中有一个 main.f90。 f77 子程序文件在/ex/src 中。子程序文件再次使用 BLAS 和 LAPACK 库。对于 BLAS 和 LAPACK,我必须使用英特尔数学核心函
我的团队最近从 2015 年英特尔编译器(并行工作室)升级到 2018 年版本,我们遇到了一个链接器问题,让每个人都焦头烂额。 我有以下类(为简洁起见进行了适度编辑),用于处理子进程的包装以及与它们对
在最后几天,我观察到我无法解释的新工作站的行为。对这个问题做一些研究,INTEL Haswell architecture 中可能存在一个可能的错误。以及在当前的 Skylake Generation
我的 HAXM 安装存在问题。事情是这样的。每次尝试为我的计算机安装 HAXM 时,我都会收到此错误: 问题是,我的计算机支持虚拟化技术(见下图)。知道如何解决这个问题吗? 最佳答案 只需执行以下步骤
我是一名优秀的程序员,十分优秀!