问题标签 [instruction-encoding]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
assembly - 使用立即操作数编码 x86-16 指令
我正在尝试解码指令,目前在 80x86 16 位机器上,我在解码没有立即值作为源操作数的指令时没有很多问题,当源操作数不再是寄存器或位置内存,但立即值。下面的指令我会这样解码:
相反,这是不公平的。这是正确的解码:
假设源操作数是立即值,有人可以向我解释解码是如何工作的吗?
assembly - 给出每条指令的操作码和代码字节数
我目前正在上一个低级编程课程,不幸的是,我在我们的教科书中找不到这些信息(大部分问题都没有包含在我们的课文中)。我很难确定如何解决这些问题。没有关于“CPU 或任何类似的东西”的信息。问题如下:
给出每条指令的操作码和代码字节数。
(a) mov exc, 984 Op Code_____ 字节数_____
(b) xchg eax, ecx Op Code_____ 字节数_____
还有很多,但如果有人可以帮助我理解如何做到这两个,我希望能够将其转化为其他问题。
我尝试了一件事,但不确定我看到了什么:我在 Visual Studio 2019 中创建了一个小型 *.asm 项目,并在 (a) 中添加了那一行代码并查看了列表文件。我看到它显示以下内容:
我不确定是否可以在这里找到这些信息,而我只是错过了它,或者还有其他方法可以解决这个问题。
assembly - 什么是 REX 前缀是指令编码?
我的教授开始自相矛盾,所以我需要你的帮助。
在指令编码中,我们有一个可选字段 REX 前缀,其拆分如下:
我问我的教授“使用 64 位数据时”的真正含义,每次我得到不同的答案:
当使用添加到 x64 的新寄存器时,如 r9、r10、r9d 等...
当使用 rax、rbx、r9 等 64 大小的寄存器时...
当指令使用(读/写)内存中的 64 位数据时。
我真的很困惑,正确的答案是什么(可能都不是,因为我不再信任我的教授了)。
assembly - 编码 8 位操作数大小?是否有类似 16 位的前缀?
在指令编码中默认大小为:
我们可以使用 legacy 前缀:
使操作数大小为 16。如果我想让它成为 8 位而不是 16 位怎么办?
assembly - 了解指令编码?
我用一个网站来编码这个:
并得到:
多亏了你,我几乎明白了一切,除了 2 个小点:
- 在这里,我们将 2 字节立即移动到 4 字节地址。他们使用 C7 操作码,根据我的表,我的意思是以下之一:
- 将 imm16 移动到 r/m16
- 将 imm32 移动到 r/m32
- mov imm32(符号扩展)到 r/m64
为什么没有匹配?
- 为什么立即数是 2 个字节?根据什么?
assembly - 英特尔在哪里记录了 ModR/M 字节中扩展寄存器 (R8-R15) 的编码?
我正在使用最新的官方“英特尔® 64 和 IA-32 架构软件开发人员手册组合卷:1、2A、2B、2C、2D、3A、3B、3C、3D 和 4 ”作为参考来了解机器级别x86-64 ISA 的编码。
第 2 卷第 2.1.3 节中提供的 ModR/M 和 SIB 字节文档给出了引用 8 位、16 位和 32 位寄存器的准确编码(表 2-1、2-2 和 2 -3)
但是,我找不到一个类似的表来指定 REX 前缀中的 REX.X、REX.B、REX.R 字节如何与 ModR/M 结合来指定扩展寄存器。我专门为每个扩展寄存器寻找显式二进制编码。据我所知,手册中有关 REX 前缀的文档仅指定使用 REX 中的相应位在 MSB 中将 reg、r/m 字段扩展 1 位,但实际上并未给出显式映射位组合。
英特尔文档是否在 SDM 的任何位置明确说明了这些映射?还是只是假设 R8-R15 将遵循明显/自然的映射策略,其中 REX.B/X/R 设置为 1 并且 R8 编码为 000,R9 为 001 ... R15 为 111 ?
assembly - x86 子指令操作码混淆
玩了一下 Turbo Assembler 和 Turbo Debugger,我对操作码感到惊讶。更准确地说,我有一些组装的二进制文件,其中 Turbo Debugger 反汇编了这个词
正确地sub bx, ax
. 然而,Turbo Assembler 将相同的指令汇编sub bx, ax
为以下字
对此感到困惑,我发现这个参考文献指出从寄存器中减去寄存器确实可能以29
and开头2B
。真的是完全相同的指令可以用不同的操作码来表达吗?如果是这样,那是为什么?是因为历史原因和兼容性吗?参考说明了操作码的不同操作数类型,它们只是在sub bx, ax
. 这是为了以后通过自修改代码等修补不同操作数的能力吗?此外,Turbo Assembler 是否具有语法结构来选择一个操作码而不是另一个操作码?
注意:我知道条件跳转喜欢je
并jz
具有相同的操作码,因为它们具有相同的标志相关行为,并且存在不同的助记符以反映同一操作的不同语义,但前者让我感到困惑。
assembly - 指令解码器如何区分前缀和主操作码?
我正在尝试围绕 x86 指令编码格式进行思考。我阅读的所有资料仍然使这个主题令人困惑。我开始有点理解它,但我无法理解的一件事是 CPU 指令解码器如何区分操作码前缀和操作码。
我知道指令的整个格式基本上取决于操作码(当然在操作码中定义了额外的位字段)。有时指令没有前缀,操作码是第一个字节。解码器怎么知道?
我假设指令解码器能够分辨出差异,因为操作码字节和前缀字节不会共享相同的二进制值。所以解码器可以判断字节中唯一的二进制数是指令还是前缀。例如(在本例中,我们将坚持使用单字节操作码)REX或LOCK前缀不会与架构指令集中的任何操作码共享相同的字节值。
assembly - Encoding memory operands using the RSP register in x64 - SIB byte needed?
I'm trying to understand how to encode reads on the RSP register in x86-64.
For example, I have some code like this:
When I assemble and dump the output, it looks like this:
push (%rsp)
becomes ff 34 24
. From what I understand, 0xFF is the opcode for PUSH, and 0x34 is Mod/RM encoding. I don't understand where 0x24 is coming from though. Is this the SIB byte? How is this instruction encoded? I can't seem to follow the Intel manual well enough to figure out where this byte comes from. I see the same byte in mov (%rsp), %rax
.