首先,您需要很好地掌握编程,使用像 C 这样的语言,因为它的级别与汇编之前的级别差不多——其他语言也很棒,但隐藏了更多低级别的细节。
C 有指针,这在汇编语言中很常用,所以在 C 中我们可以有一些算法的数组版本,也可以有相同的指针版本。在学习汇编之前了解/理解这些东西是很好的。
此外,您还需要很好地掌握调试技巧——逐行观察您的程序运行;观察变量变化;观察控制流;将复杂的语句分解成更简单的语句,这样您就可以看到它们内部发生了什么。调试技能是编程的要求,在汇编中更是如此。
高级语言提供:
- 已命名、具有作用域、生命周期/持续时间、已键入并且可以根据其类型保存值的变量
- 易于嵌套的结构化语句/控制结构
- 用容易熟悉的(数学)符号编写的表达式
相比之下,汇编/机器代码提供:
- 仅存在的物理存储,没有范围,生命周期/持续时间,无类型等。
- 控制结构的 if-goto-label 样式
- 操作存储和计算的说明
这些汇编功能在所有处理器中都是通用的。
要学习汇编,最好能够将高级语言结构与处理器的功能联系起来。一种方法是尝试将用 C 或伪代码编写的小程序翻译成汇编。
尤其是在学习汇编语言时,知道自己在尝试做什么总是一个好主意,这意味着首先拥有/编写一个算法,最好是可以测试该算法以便知道它可以工作,因为 C 中的小设计更改有时会导致汇编中的重大更改(例如重写)。一种方法是使用伪代码在纸上执行此操作,但我建议使用高级语言(首选 C)编写,以便您可以实际运行和测试您的算法。
将算法转换为程序集:
- 将数据类型转换为物理存储概念,考虑大小、偏移和对齐方式
- 将全局变量转换为物理存储预留
- 将函数转换为程序集:
- 将参数和局部变量转换为物理存储,考虑使用情况、生命周期、大小和类型,以及与其他变量的重叠。
- 将结构化控制语句转换为 if-goto-label 中的等效模式
- 将表达式翻译成机器代码指令
以上讨论应该让您了解所有汇编语言之间的共同点。学习一种汇编语言意味着理解上述主题,以及学习某些特定处理器的实际指令集。您在一个处理器上学到的大部分知识都会转移到另一个处理器上,特别是如果您可以将上述广泛/常见的概念与任何给定指令集的细节区分开来。
指令集在可用寄存器的数量、条件(if-goto-label)分支的执行方式、立即操作数的大小、二元运算符允许的操作数数量方面有所不同:两个与三个,如何存储被访问,许多其他细节。正如其他人在对您的问题帖子的评论中所说的那样,即使对于相同的硬件,寄存器的使用方式和为不同操作系统传递的参数也可能存在差异。
要开始学习汇编语言,我建议先选择一种简单的处理器来学习物理存储、控制结构模式、表达式求值和函数调用的概念。也许指令编码也是如此,特别是如果您的兴趣倾向于处理器内部。
相当简单但真实和现代:RISC V,与 MIPS 非常相似,都具有良好的 PC 模拟器以及大量在线学习资料。此外,这些处理器是真实的,具有可用的编译器,可以将 C 代码转换为汇编供您检查。
更简单的是 LC-3 — 一个非常基本的、易于学习的、面向教育的(玩具)处理器,具有良好的模拟器支持。缺点是缺乏真正的编译器支持,但优点是简单——它的局限性使这个处理器非常简单易懂。
x86 是一个非常常见的处理器,尽管它背负了数十年的包袱,当您了解其历史和演变时,其中的大部分内容是合情合理的;否则从头开始学习可能会过于复杂。