4

我正在尝试将原始机器代码字节作为 0 和 1 写入文本文件,并通过 BIOS 执行它。

然而,我在理解寻址、乘法、偏移、寻址、操作数和指令如何在组合排列中工作时遇到了一些问题,即MOV AL, 07和之间的区别MOV BL, AL

我的意思是它在汇编中是有意义的,但在机器代码中,很难理解参数的概念。

所以我想知道的是:我怎样才能更好地理解这一点?我发现没有教程可以准确地解释/描述数据传递、MMIO、寻址模式、算术等之间的组合相关性或连接中的指令中的 0 和 1。

在这个网站http://ref.x86asm.net/coder32.html#x00它尝试,但我不明白这一点。

示例:假设我想将 5 移入 AL ... 我是否将二进制中的文字“5”指定为与 AL/MOV 指令链接的二进制前缀中的操作码的一部分,或者我是否将为每个二进制代码指定一个固定的二进制代码指令,不管价值?这就是我想知道的......如何理解机器代码是如何编写的。

4

2 回答 2

5

不幸的是,x86 编码复杂且不规则,理解它是一项艰巨的工作。编码的最佳“快速入门”是 sandpile.org 上的一组 HTML 页面(它很简洁,但非常全面)。

首先:http ://sandpile.org/x86/opc_enc.htm - “指令编码”表显示了十几种指令编码方式。每行中的白色单元格代表指令中的强制字节;根据操作码中较早出现的各种字段,存在(或不存在)以下灰色单元格。您应该查看以白色“0Fh”开头的行以及第一行。在同一页面的底部是出现在各种“扩展”操作码字段中的位域 - 您忽略了除“modrm/sib”行(第一行)之外的所有内容。

请注意,对于除第一行(即 1 字节操作码)之外的所有行,“mod r/m”字节必须跟在操作码之后(对于 1 字节操作码,它取决于指令)。这对大多数 2 参数指令的参数进行编码。http://sandpile.org/x86/opc_rm.htm中的表具有以下含义:一个参数必须是寄存器,另一个参数可以是寄存器或内存间接(“reg”字段对寄存器进行编码, “mod”和“r/m”字段对另一个参数进行编码)。操作码的其他地方通常还有一个“方向”位,指示参数的顺序。操作码还指示我们是否正在操作,例如 AL、AX、EAX 或 RAX(即不同大小),或扩展寄存器之一,

在 modrm 中,如果“mod”位为“11”,则“r/m”字段也指寄存器。否则,它通常指的是通过将命名寄存器添加到出现在 modrm 字节之后的(可选)位移来构造的内存地址(此常量的长度为 0、1 或 4 字节,具体取决于“mod”位)。例外情况是当“r/m”位为“100”(即 0x4)时,通常命名为“SP”——在这种情况下,内存参数由紧跟 modrm 字节的附加“sib”字节描述(任何 modrm 位移出现在 sib 之后)。对于 SIB 的编码,请查看http://sandpile.org/x86/opc_sib.htm,或从 modrm 页面单击。

最后,要了解方向和大小的来源,请查看一些操作码:http ://sandpile.org/x86/opc_1.htm 。前四个条目都是“ADD”,参数有两种不同的顺序,并且有两种不同的宽度。所以在这种情况下,指令的低位编码方向和宽度。

于 2013-09-15T22:59:26.980 回答
1

汇编程序助记符和机器指令之间(主要)存在一对一的映射。您可以在英特尔软件开发人员手册第 2 卷中找到这些映射,其中包含完整的 x86 16 位、32 位和 64 位指令集。您可能希望从第 2 章开始:指令格式,它描述了您试图提出的翻译。

在这种情况下,mov al, 5正如您所说,您将文字放在那里。机器代码中的指令是:

b0 05

因为那是指令的MOV r8, imm8形式。MOV对于mov bl, al,您需要MOV r/m8,r8表单,在您的情况下将编码为:

88 c3

c3您可以在表 2-2 使用 ModR/M 字节的 32 位寻址形式中查找,您将在其中看到它BL在行和AL列的交叉处。(如果这是您所处的模式,也有一个 16 位表 - 在这种情况下的值是相同的。)

于 2013-09-05T21:59:12.410 回答