Assembly 汇编语言到机器代码 我用下面的代码创建了一个简单的C++源文件。 int main() { int a = 1; int b = 2; if(a < b) { return 1; } else if(a > b) { return 2; } else { return 3; } intmain(){ INTA=1; int b=2; if(ab){ 返回2; } 否则{ 返回3; }
} 我使用objdump命令获取上述源代码的汇编代码。 线路呢 intb=2;转换为mov DWORD PTR[rbp-0x4],0x2 其对应的机器代码(十六进制格式)为c7 45 fc 02 00Assembly 汇编语言到机器代码 我用下面的代码创建了一个简单的C++源文件。 int main() { int a = 1; int b = 2; if(a < b) { return 1; } else if(a > b) { return 2; } else { return 3; } intmain(){ INTA=1; int b=2; if(ab){ 返回2; } 否则{ 返回3; },assembly,binary,x86-64,Assembly,Binary,X86 64,} 我使用objdump命令获取上述源代码的汇编代码。 线路呢 intb=2;转换为mov DWORD PTR[rbp-0x4],0x2 其对应的机器代码(十六进制格式)为c7 45 fc 02 00 我想知道如何将汇编代码转换为二进制代码。我阅读了x86-64的《英特尔参考手册》,但无法理解,因为我不熟悉低级编程。您应该阅读《英特尔手册》,它解释了如何做到这一点。为了更简单的参考。x86指令的编码方式相当简单,但可能性有点大 简而言之,x86指令包含以下部分,其中除操作码外的所有部分都可能缺失
我想知道如何将汇编代码转换为二进制代码。我阅读了x86-64的《英特尔参考手册》,但无法理解,因为我不熟悉低级编程。您应该阅读《英特尔手册》,它解释了如何做到这一点。为了更简单的参考。x86指令的编码方式相当简单,但可能性有点大 简而言之,x86指令包含以下部分,其中除操作码外的所有部分都可能缺失:
prefix opcode operands immediate
前缀
字段可能会修改指令的行为,这不适用于您的用例。您可以在引用中查找操作码
(我喜欢),例如,mov r/m32,imm32
是C7/0
,这意味着:操作码是C7
,两个操作数中的一个作为扩展操作数为零。此指令采用32位立即数,因此该指令的形式为
C7 operand/0 imm32
操作数/扩展操作码编码为modr/m字节,对于某些寻址模式,可选sib(刻度索引基)字节,可选8位或32位位移。您可以查找所需的值。因此,在您的例子中,您希望对内存操作数[rbp]
进行编码,使用一个字节位移和一个0的寄存器操作数,从而生成modr/m字节45
。所以编码是:
C7 45 disp8 imm32
现在我们将8位位移编码为2的补码<代码>-4对应于FC
,因此这是
C7 45 FC imm32
最后,我们对32位立即数进行编码,您希望它是2
。请注意,它是以little endian表示的:
C7 45 FC 02 00 00 00
这就是指令的编码方式。您应该阅读英特尔手册,它解释了如何进行编码。为了更简单的参考。x86指令的编码方式相当简单,但可能性有点大 简而言之,x86指令包含以下部分,其中除操作码外的所有部分都可能缺失:
prefix opcode operands immediate
前缀
字段可能会修改指令的行为,这不适用于您的用例。您可以在引用中查找操作码
(我喜欢),例如,mov r/m32,imm32
是C7/0
,这意味着:操作码是C7
,两个操作数中的一个作为扩展操作数为零。此指令采用32位立即数,因此该指令的形式为
C7 operand/0 imm32
操作数/扩展操作码编码为modr/m字节,对于某些寻址模式,可选sib(刻度索引基)字节,可选8位或32位位移。您可以查找所需的值。因此,在您的例子中,您希望对内存操作数[rbp]
进行编码,使用一个字节位移和一个0的寄存器操作数,从而生成modr/m字节45
。所以编码是:
C7 45 disp8 imm32
现在我们将8位位移编码为2的补码<代码>-4对应于FC
,因此这是
C7 45 FC imm32
最后,我们对32位立即数进行编码,您希望它是2
。请注意,它是以little endian表示的:
C7 45 FC 02 00 00 00
这就是指令的编码方式。你说的“转换”是什么意思?使用程序?手动操作?手动转换。
intb=2代码>不是汇编语言。不同之处在于,C是编译语言,因此行intb=2
可以以多种不同的方式实现(甚至完全由优化器删除),这取决于编译器将决定什么,如何生成机器代码,从而生成C语言标准定义的结果。汇编语言在某种程度上是不同的,汇编程序不是这种类型的编译器,当你在汇编add rax,rbx
中编写时,它将被编译成那样,不改变指令,也不被某种优化器删除,所以这更像是“1:1转换”。你说的“转换”是什么意思?使用程序?手动操作?手动转换。intb=2代码>不是汇编语言。不同之处在于,C是编译语言,因此行intb=2
可以以多种不同的方式实现(甚至完全由优化器删除),这取决于编译器将决定什么,如何生成机器代码,从而生成C语言标准定义的结果。汇编语言在某种程度上是不同的,汇编程序不是这种类型的编译器,当你在汇编中编写rax,rbx时,它将被编译成那样,不改变指令,也不被某种优化器删除,所以这更像是“1:1转换”。所以在你提供的代码中,我转到了C7 1字节操作码,它是用于MOV指令的。但是两个操作数Evqp和IVD意味着什么,它们是否对应于rm32寻址和立即数?感谢您提供帮助,了解字段的含义。我链接的参考资料高度浓缩,但更难阅读。好的,很好。另一个问题是你说“我想用1字节位移(8位)[DWORD PTR[rbp-0x4]]对rbp寄存器进行编码”,当我看到表中的MOD r/m时,我也看到了32位位移的版本,你能给我举个例子吗?@AbhisheykDeb用32位位移,编码将是C7 85 FC FF FF 02 00
,其中modr/m字节是85
而不是45
,位移是FC FF FF
@AbhisheykDeb,48
前缀是REX.W