我相信编写反汇编程序。从一个非常简单的一两行程序开始,它可能会加载一个带有常量的寄存器(必须阅读教程或其他东西来学习该步骤)。组装它。以您能够或愿意编写程序来读取的格式保存二进制文件(也许是英特尔十六进制,或者如果他们支持,则为精灵)。
编写一个程序来读取二进制文件并提取程序,然后获取这些字节并编写一个反汇编程序(即使供应商有一个反汇编程序,您仍然应该编写一个)。
现在开始迭代过程,学习一条新指令或使用该指令的新方法,一次一条指令。编写代码来反汇编该指令或选项。尝试编写汇编程序来操作指令中的每个位。
当你读完指令集时,你会比大多数每天使用它的人更了解指令集,你会知道如何为每个操作码的每个选项编写汇编程序,你也可以了解为什么这个指令只能从其位置寻址 N 个字节,而其他指令可以访问任何内容,或者该指令只能使用 N 位立即数,而其他指令可以使用任何值。之类的东西。
这个过程我用过很多次,学习了很多指令集,ymmv。在前两三个之后,上述过程可能只需要一个下午即可完成。
编辑:
这里的目标是教育而不是下一个伟大的 sourceforge 项目。输出可以像你喜欢的那样丑陋或不完整,你是唯一会阅读它的人。
注意:可变长度指令集的通用反汇编器可能有些困难,您不想线性反汇编二进制文件,在这种情况下您想遵循所有执行路径。我会避免它。即使在可变长度指令集上,采用执行某种线性汇编然后反汇编的简单程序也不困难。如果编译器没有汇编器输出选项或没有反汇编器,您可以通过反汇编和检查 C 编译器(或其他高级语言)的输出来了解指令集利用这一点(除非它是一个固定长度的指令集)。
另请注意,一旦您为一个处理器学习了汇编程序,第二个处理器就会容易得多,依此类推。你需要从一个到下一个学习的东西通常是这个跳跃有多大,立即数的规则是什么,间接寻址,基本上所有与检查操作码直接相关的东西。您可以在不查看操作码的情况下学习它,但您必须依赖高质量的文档或汇编程序错误消息。