我正计划编写自己的小型反汇编程序。我想解码我在读取可执行文件时获得的操作码。我看到以下操作码:
69 62 2f 6c 64 2d 6c
Run Code Online (Sandbox Code Playgroud)
必须对应于:
imul $0x6c2d646c,0x2f(%edx),%esp
Run Code Online (Sandbox Code Playgroud)
现在,“imul”指令可以有两个或三个操作数。我如何从那里的操作码中弄清楚这一点?
它基于英特尔的 i386 指令集。
哪里可以找到带有相应允许操作数及其大小的dalvik操作码列表(8位/ 16位/ 32位/ 62位)
在参考指南中,我看到MOV操作码是 88、89、8A 等。为什么一条指令有多个操作码?
每次我在IL中使用它们:br_S,ldc_i4_S,ldarg_S等等......所以我只需要问这个问题:
我的意思是......如果你是从IL到本地汇编程序的JIT语言,它在性能方面应该不重要,对吧?那么这些"短手"符号的目的是什么?是仅仅因为IL二进制文件中的字节数较少(例如作为压缩机制)还是有其他原因?
如果它只是一个压缩机制,为什么不使用压缩算法,如deflate?
我的问题源于一个简单的好奇心:
为什么在x64中某些操作码是无效的(例如06,07),而在x86中用于相当基本的指令(06和07是推送和弹出)?我认为那些最简单的指令在两种架构中都能很好地完成.
为什么他们在x64中禁用了一些简单的指令?他们为什么不工作?为什么他们禁用某些操作码,在操作码列表中创建漏洞,何时可以将它们分配给x64版本的指令?
参考:
在通过RISC-V规范时,我注意到64位版本与32位版本的不同之处在于,
这使得RV32代码不兼容RV64。但是,如果64位版本已经实施方式:
ADD/SUB/SHL/..到ADDW/SUBW/SHLW/..与标志让他们只能在32位操作系统上延伸。ADD/SUB/SHL/..或ADDD/SUBD/SHLD/..在全部64位行为这样,RV32程序也可以在RV64上运行。为了实现CPU,工作量将保持不变,因为在两种情况下都必须实现64位和32位指令,而只有64位和32位版本的操作码将被交换。符合规范。(除了乘法指令。)
那么,为什么RISC-V为什么决定将新的操作码分配给RV64中的32位操作而不是64位操作?
我一直试图了解0x40ASM x64 指令的REX 操作码的用途。例如,在 Kernel32.dll 的这个函数序言中:
如您所见,它们push rbx用作:
40 53 push rbx
Run Code Online (Sandbox Code Playgroud)
但仅使用53h操作码(不带前缀)也会产生相同的结果:
根据此站点,REX 前缀的布局如下:
所以40h操作码似乎没有做任何事情。有人可以解释它的目的吗?
在构建芯片 8 仿真器时,我遇到了芯片 8 信息的 2 个主要来源似乎不同的问题,这对整个芯片 8 解释器有影响。
一方面,我们有维基百科,它在操作码 FX65 下告诉我们
“用从地址 I 开始的内存中的值填充 V0 到 VX(包括 VX)。对于每个写入的值,I 增加 1。”
其中“对于写入的每个值,I 增加 1。” 是重要的部分。
遵循此结果会产生以下代码:
for(int i = 0; i <= ((opcode & 0x0F00) >> 8); ++i) {
V[i] = memory[I];
++I;
}
Run Code Online (Sandbox Code Playgroud)
另一方面,我们有cowgod的chip-8 参考,几乎每个教程都链接到的参考,它告诉我们以下内容
“解释器从位置 I 开始的内存读取值到寄存器 V0 到 Vx。”
应用此逻辑会产生以下代码(这也是大多数芯片 8 实现使用的实现):
for(int i = 0; i <= ((opcode & 0x0F00) >> 8); ++i) {
V[i] = memory[I …Run Code Online (Sandbox Code Playgroud) 我已将问题缩小到此代码
$a = 3;
$a = 3 * $a++;
echo $a; //9
$a = 3;
$a = $a * $a++;
echo $a; //12
Run Code Online (Sandbox Code Playgroud)
这是第一次操作的 VLD 操作码
compiled vars: !0 = $a
line #* E I O op fetch ext return operands
-------------------------------------------------------------------------------------
2 0 E > ASSIGN !0, 3
3 1 POST_INC ~2 !0
2 MUL ~3 ~2, 3
3 ASSIGN !0, ~3
4 4 ECHO !0
5 5 > RETURN 1
Run Code Online (Sandbox Code Playgroud)
用于第二次操作 ($a * $a++)
compiled vars: !0 = …Run Code Online (Sandbox Code Playgroud)