- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我打算编写自己的小型反汇编程序。我想对读取可执行文件时得到的操作码进行解码。我看到以下操作码:
69 62 2f 6c 64 2d 6c
必须与以下内容相对应:
imul $0x6c2d646c,0x2f(%edx),%esp
现在,“imul”指令可以具有两个或三个操作数。如何从我那里的操作码中找出答案?
最佳答案
尽管x86指令集非常复杂(无论如何都是CISC),并且我看到这里的许多人不鼓励您尝试理解它,但是我会说相反的话:它仍然可以理解,您可以从中学习为什么如此复杂,以及英特尔如何设法将其从8086一直扩展到现代处理器。
x86指令使用可变长度编码,因此它们可以由多个字节组成。每个字节用于编码不同的事物,其中一些是可选的(无论是否使用这些可选字段,它都在操作码中进行编码)。
例如,每个操作码可以在0到4个前缀字节之前,这是可选的。通常,您无需担心它们。它们用于更改操作数的大小,或者用作转义码,并带有现代CPU(MMX,SSE等)的扩展指令到操作码表的“第二层”。
然后是实际的操作码,通常为1个字节,但对于扩展指令,最多可以为3个字节。如果仅使用基本指令集,则也不必担心它们。
接下来,有一个所谓的ModR/M
字节(有时也称为mode-reg-reg/mem
),它对寻址模式和操作数类型进行编码。仅由具有任何此类操作数的操作码使用。它具有三个位字段:
ModR/M
字节之后,可能还有另一个可选字节(取决于寻址模式),称为
SIB
(
S
cale
I
ndex
B
ase)。它用于更特殊的寻址模式,以对比例因子(1x,2x,4x),基址/寄存器和索引寄存器进行编码。顾名思义,它的布局与
ModR/M
字节相似,但是左起(最高有效)的前两位用于对小数位进行编码,后三位和后三位用于对索引和基址寄存器进行编码。
ACDB
。也就是说,对于8位指令,寄存器代码的最低两位对A,C,D和B寄存器进行相应编码:
00
=
A
寄存器(累加器)
01
=
C
寄存器(计数器)
10
=
D
寄存器(数据)
11
=
B
寄存器(基本)
second
+---+---+
f | 0 | 1 | 00 = A
i +---+---+---+ 01 = C
r | 0 | A : C | 10 = D
s +---+ - + - + 11 = B
t | 1 | D : B |
+---+---+---+
second second 0 00 = AL
+----+----+ +----+----+ 0 01 = CL
f | 0 | 1 | f | 0 | 1 | 0 10 = DL
i +---+----+----+ i +---+----+----+ 0 11 = BL
r | 0 | AL : CL | r | 0 | AH : CH |
s +---+ - -+ - -+ s +---+ - -+ - -+ 1 00 = AH
t | 1 | DL : BL | t | 1 | DH : BH | 1 01 = CH
+---+---+-----+ +---+----+----+ 1 10 = DH
0 = BANK L 1 = BANK H 1 11 = BH
0
,这是一条8位指令。但是,如果该位置1(即操作码为奇数),则该指令为16位。在这种模式下,两位像以前一样对
ACDB
寄存器之一进行编码。模式保持不变。但是,它们现在对完整的16位寄存器进行编码。但是,如果还设置了第三个字节(最高字节),它们将切换到另一整个寄存器组,称为索引/指针寄存器,它们是:
SP
(堆栈指针),
BP
(基本指针),
SI
(源索引) ,
DI
(目标/数据索引)。因此,寻址方式如下:
second second 0 00 = AX
+----+----+ +----+----+ 0 01 = CX
f | 0 | 1 | f | 0 | 1 | 0 10 = DX
i +---+----+----+ i +---+----+----+ 0 11 = BX
r | 0 | AX : CX | r | 0 | SP : BP |
s +---+ - -+ - -+ s +---+ - -+ - -+ 1 00 = SP
t | 1 | DX : BX | t | 1 | SI : DI | 1 01 = BP
+---+----+----+ +---+----+----+ 1 10 = SI
0 = BANK OF 1 = BANK OF 1 11 = DI
GENERAL-PURPOSE POINTER/INDEX
REGISTERS REGISTERS
66
前缀(操作数大小覆盖)来翻转它。偶数操作码(“短”操作码)始终为8位。因此,在32位CPU中,寄存器代码为:
0 00 = EAX 1 00 = ESP
0 01 = ECX 1 01 = EBP
0 10 = EDX 1 10 = ESI
0 11 = EBX 1 11 = EDI
ACDB
模式保持不变。
SP,BP,SI,SI
模式也保持不变。它只使用较长版本的寄存器。
7*
行中。还有一整行
B*
保留给
mov
指令,这是将立即值(常量)加载到寄存器中的简写形式。它们都是紧随其后的立即数的一字节操作码,因为它们在操作码中编码目标寄存器(它们由该表中的列号选择)以其三个最低有效字节(最右边的字节)进行编码。它们遵循相同的模式进行寄存器编码。第四位是“短”/“长”选择一个。
imul
指令在表中恰好位于
69
位置(呵呵; J)。
ModR/M
字节中编码的两个寄存器之一是源,而目的地是哪一个(这适用于带有两个寄存器操作数的指令)。
ModR/M
字节的寻址模式字段,以下是对它的解释:
11
是最简单的:它对寄存器到寄存器的传输进行编码。一个寄存器由该字节的后三个位(reg
字段)编码,另一个寄存器由该字节的其他三个位(R/M
字段)编码。 01
表示在此字节之后,将出现一个字节的位移。 10
的含义相同,但是使用的位移为4字节(在32位CPU上)。 00
是最棘手的:它表示间接寻址或简单替换,具体取决于R/M
字段的内容。 SIB
字节,则通过
100
位中的
R/M
位模式来发出信号。还有一个仅用于32位位移模式的代码
101
,它根本不使用
SIB
字节。
Mod R/M
11 rrr = register-register (one encoded in `R/M` bits, the other one in `reg` bits).
00 rrr = [ register ] (except SP and BP, which are encoded in `SIB` byte)
00 100 = SIB byte present
00 101 = 32-bit displacement only (no `SIB` byte required)
01 rrr = [ rrr + disp8 ] (8-bit displacement after the `ModR/M` byte)
01 100 = SIB + disp8
10 rrr = [ rrr + disp32 ] (except SP, which means that the `SIB` byte is used)
10 100 = SIB + disp32
imul
:
69
是它的操作码。它对
imul
的版本进行编码,该版本不对8位操作数进行符号扩展。
6B
版本会对其进行符号扩展。 (如果有人要求,它们的区别在于操作码中的位1。)
62
是
RegR/M
字节。二进制形式是
0110 0010
或
01 100 010
。前两个字节(
Mod
字段)表示间接寻址模式,位移为8位。接下来的三位(
reg
字段)为
100
,并将
SP
寄存器(在本例中为
ESP
,因为我们处于32位模式)编码为目标寄存器。最后三位是
R/M
字段,我们在其中有
010
,它将
D
寄存器(在本例中为
EDX
)编码为所使用的其他(源)寄存器。
2f
是位移,为正数(十进制为+47)。
imul
指令所必需的。在您的情况下,这是
6c 64 2d 6c
,在little-endian中是
$6c2d646c
。
关于assembly - 从操作码中查找指令中的操作数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6924912/
我在 GlassFish (J2EE_1.4) 上的 NetBeans 中开发企业项目。我的项目中有一些实体 bean、一些 session bean 和消息驱动 bean。我以如下方式使用 serv
什么在速度方面更好...... 我正在尝试确定用户是否已将某个 URL 添加到他们的快捷方式列表中。如果他们添加了 URL,页面上就会有一个链接,用于从快捷方式中删除该页面,否则他们可以将其添加到快捷
我的问题如下: 我打开一个Excel-File,但我不知道我的客户在模板文件中使用了哪些可能的标头变量。它们可以是:#DATE,#TIME,#NAME等。因此,我需要查找这些变量,以及是否已使用过:替
我有一堆以“-e”结尾的文件要删除。 $ find . -name "*-e" exec rm {} \; find: exec: unknown primary or operator 正则表达式是
我有一个简单的问题:是否可以在 TypeScript 中获取联合的一部分的类型? 例如,您可以经常使用如下查找类型: interface Person { name: string; } type
我正在尝试设置 Point Cloud Library启用 CUDA 选项的主干构建。 我相信我已经按照 these instructions 正确安装了 CUDA . 在 PCL 构建的 cmake
我将首先说我所知道的唯一 VBA 是操作录制的宏的反复试验。我是一名注册会计师,试图以艰难的方式学习 VBA(并希望我去学校学习计算机编程!)。 我有带有多个工作表的大型工作簿。 G 列中以黄色突出显
当文件数达到阈值时,我试图删除目录中最旧的文件。 list_of_files = os.listdir('log') if len([name for name in list_of_files
我有一个数组,它有一些重复的值。 我必须计算每个重复项的数量及其索引。 打印如: Index of b: 1 Index of b: 4 Index of c: 2 Index of c: 3 Ind
我已经搜索了我的问题的解决方案,但没有成功。热键 ctrl+F 找到的 eclipse 查找/替换功能不起作用。注意:通过 Eclipse 菜单 Edit>Find Replace(不工作我的意思是
我想检查 div 是否包含类为“error”的子级,但条件是错误类显示不等于无。 (意味着错误类必须可见。 如何更改我的以下代码: $(".related_field").each(function
这个问题已经有答案了: 已关闭13 年前。 Possible Duplicate: Can jQuery provide the tag name? 嗨! 这个问题太基础了,我不好意思问,但我尝试了
我一直听说这是 cygwin 的路径问题。它阻止了 emacs 在我的 cygwin 中工作。当我在 cli(不是 bash/cygwin)上执行 find 时,无论我输入什么,我都会得到同样的错误。
我正在使用此变量来获取一个或多个与我需要的值相匹配的值。 var mail = $("#dat").contents().find("td:contains('" + name + "')" ).si
请原谅这个长问题。我只是不确定解决这个问题的最佳方法是什么。 我有一个电子表格(Google 表格),其中包含用户和地址列表,我需要从中创建邮寄标签。该电子表格是从我们的学生信息系统导出的。这些地址应
我正在 Excel VBA 中创建一个公式,以解析单元格中以逗号分隔的“部分”列表。在另一个工作表中查找具有该零件名称的单元格,然后使用找到的该单元格的地址来获取同一行不同列的零件成本。我为此工作了数
我被要求在网络应用程序上实现一些电子邮件地址验证 - 我确信我们都已经经历过一千次了...但是,这一次我被要求在域上进行 MX 查找查看它是否接受电子邮件。 有人知道这样做有任何潜在的问题吗? mx
我有一个切换按钮,可读取.wave文件,并且字符串更改为暂停,然后..... 我的问题是,当用户播放声音时,按钮字符串更改为暂停,结束声音后,该字符串仍为暂停状态,我想将其更改为播放。但是我不知道如何
对于令人困惑的标题提前表示歉意。我的问题如下,我在大约 600 个文件中有以下文本: $_REQUEST['FOO'] 我想将其替换为以下内容: $this->input->post('FOO') 为
我正在使用 Ansible 的查找功能查找 INI 文件中的值。这是文档中的示例: - debug: msg="User in integration is {{ lookup('ini', 'use
我是一名优秀的程序员,十分优秀!