Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
汇编程序如何将x86指令助记符映射到二进制机器指令?_X86_Assembly - Fatal编程技术网

汇编程序如何将x86指令助记符映射到二进制机器指令?

汇编程序如何将x86指令助记符映射到二进制机器指令?,x86,assembly,X86,Assembly,我对编写x86汇编程序感兴趣。我想知道将x86汇编助记符指令(使用类似英特尔的语法)映射到相应的二进制机器代码指令的好方法是什么。对于x86,它非常复杂。自从32位处理器接管以来,复杂度有所降低,但是是的。还是很痛 您可能想看看nasm()。它是一个开源的32位汇编程序。看看他们是怎么做的。或者,改用它。:) 这只是一个直接的一对一映射;英特尔文档描述了所有指令及其编码。您需要构建一个巨大的查找表或类似的东西来进行匹配和代码生成。您想了解助记符到机器代码的物理映射吗?若有的话,本手册第2A和2B

我对编写x86汇编程序感兴趣。我想知道将x86汇编助记符指令(使用类似英特尔的语法)映射到相应的二进制机器代码指令的好方法是什么。

对于x86,它非常复杂。自从32位处理器接管以来,复杂度有所降低,但是是的。还是很痛


您可能想看看nasm()。它是一个开源的32位汇编程序。看看他们是怎么做的。或者,改用它。:)

这只是一个直接的一对一映射;英特尔文档描述了所有指令及其编码。您需要构建一个巨大的查找表或类似的东西来进行匹配和代码生成。

您想了解助记符到机器代码的物理映射吗?若有的话,本手册第2A和2B卷将描述x86机器代码的二进制格式

Wikipedia上的有一个紧凑的列表,列出了所有按照引入时间分类的指令,这可能会帮助您确定首先实现什么的优先级


但是,如果您询问如何解析汇编代码文本文件,从而使程序能够开始编写机器代码,那么您基本上需要了解如何编写编译器。lex和yacc工具是很好的起点,但是如果你不知道如何构建编译器,你还需要一本书。我认为这本书是最好的,但是还有很多其他的书可以用,所以有很多推荐书。

有些东西告诉我你从来没有看过x86编码。一个助记符可以对应多个操作码,每个操作码可以有许多前缀、大小覆盖。。。我肯定我遗漏了一些东西。我每天都写x86汇编代码。它必须是一对一的,否则您如何知道为您编写的指令发出了哪些操作码?仅仅因为有前缀、特殊修饰符、内存访问或注册版本等,并不能改变这样一个事实,即对于在汇编文件中编写的每条指令,您必须知道发出的是什么机器指令……如果您想有更多没有前缀的示例,mov eax、[ebx]和mov[eax],ebx不使用相同的操作码(我相信是89和8b)。x86编码实际上不是一个带有助记符的1-1映射。是的,汇编程序拥有从源代码生成汇编所需的所有数据。我所说的不仅仅是从助记符上。一个大的查找表可能是这些天的发展方向。回到20世纪80年代,我确信有一种更为奇特的方法,它利用特定的模式来节省空间。因为640kB没有那么大的空间。当然,他们只需要处理16位指令…@Bahbar
moveax,[ebx]
is
8b03
mov[eax],ebx
is
8918
。这看起来可能不同,但如果你看的是二进制/八进制,它是相同的操作码<代码>213 003vs
211 030
。第一个字节包含6位操作码(100010b-21o)+方向位(d=1:移动到eax/d=0:反向)+s=1(32位操作)。下一个字节的前2位为mod=0(无位移),其余6位为交换的2个寄存器(03 vs 30)。为此,您可能不需要一个成熟的编译器。您需要一个带有某种查找表的简单两次汇编程序。你可能不会总是以这种方式生成最好的代码,但你会得到一些有用的东西。@Nathan:汇编程序是一个成熟的编译器。请记住,编译器只是从其他语言到操作码的翻译器。如果你计算整个翻译过程,汇编程序和编译器最终会做完全相同的事情。碰巧大多数其他语言都足够复杂,汇编语言也足够简单,汇编语言充当了一个不错的中间点——因此许多编译器将翻译分为两个阶段:翻译到汇编,让汇编程序完成实际生成操作码的繁重工作。汇编程序通常不会从中受益。@cHao:谢谢你的澄清。这是一个有趣的问题:-)所有英特尔操作码引用都存在一个问题,即它们没有提供一个特定汇编语句如何映射到机器代码的奇怪示例。很容易在ModR/N SIB字节混乱中迷失方向…也可以读取