跳转到内容

x86 汇编/基本常见问题

来自 Wikibooks,开放世界中的开放书籍

此页面将作为初学汇编语言编程人员的基本常见问题解答。

计算机如何读取/理解汇编代码?

[编辑 | 编辑源代码]

计算机本身并不真正“读取”或“理解”任何东西,因为它没有意识或知觉,但这无关紧要。事实上,计算机无法读取你编写的汇编语言。你的汇编器会将汇编语言转换为一种称为“机器码”的二进制信息形式,计算机使用它来执行其操作。如果你不汇编代码,它对于计算机来说就是完全的胡言乱语。

也就是说,汇编很重要,因为每个汇编指令通常只对应一个机器码,而且“凡人”可以使用一张白纸、一支铅笔和一本汇编指令参考书来直接完成这项任务。事实上,在计算机的早期,这是一项常见任务,甚至在某些情况下需要“手工汇编”机器指令来编写一些基本的计算机程序。一个经典的例子是史蒂夫·沃兹尼亚克,他手工将整个 Integer BASIC 解释器汇编成 6502 机器码,用于他的最初的Apple I 计算机。然而,应该注意的是,这种为商业发行软件所做的任务非常罕见,以至于仅凭这一点就值得特别提及。很少有程序员真正为超过几个指令做过这样的事,即使是那样,也仅仅是课堂作业而已。

在 Windows/DOS/Linux 上是否相同?

[编辑 | 编辑源代码]

这个问题的答案是肯定和否定。基本的 x86 机器码只取决于处理器。Windows 和 Linux 的 x86 版本显然是建立在 x86 机器码之上的。在 Linux 和 Windows 中,x86 汇编编程之间存在一些差异。

  1. 在 Linux 计算机上,最流行的汇编器是 GAS 汇编器,它使用 AT&T 语法编写代码,以及 Netwide Assembler,也称为 NASM,它使用类似于 MASM 的语法。
  2. 在 Windows 计算机上,最流行的汇编器是 MASM,它使用 Intel 语法,但是,许多 Windows 用户也使用 NASM。
  3. Windows 和 Linux 上可用的软件中断及其功能是不同的。
  4. Windows 和 Linux 上可用的代码库是不同的。

使用相同的汇编器,在每个操作系统上编写的基本汇编代码基本相同,只是你与 Windows 的交互方式不同于你与 Linux 的交互方式。

哪个汇编器最好?

[编辑 | 编辑源代码]

简而言之,没有哪个汇编器比其他汇编器更好;这只是一个个人喜好问题。

长话短说,不同的汇编器有不同的功能、缺点等。如果你只知道 GAS 语法,那么你可能想使用 GAS。如果你知道 Intel 语法并且在 Windows 机器上工作,你可能想使用 MASM。如果你不喜欢 MASM 和 GAS 的一些怪癖或复杂性,你可能想尝试 FASM 或 NASM。我们将在第 2 节中讨论不同汇编器之间的差异。

我需要学习汇编吗?

[编辑 | 编辑源代码]

对于大多数计算机任务,你不需要学习汇编,但它绝对有用。学习汇编不是学习一门新的编程语言。如果你要开始一个新的编程项目(除非该项目是引导加载程序、设备驱动程序或内核),那么你可能想避开汇编语言,就像瘟疫一样。一个例外是,如果你绝对需要从拥塞的内部循环中挤出最后一点性能,而你的编译器正在生成次优代码。但是,请记住,过早优化是万恶之源,尽管一些计算密集型实时任务只有在从一开始就理解和计划优化技术的情况下才能获得足够的优化。

然而,学习汇编可以让你对计算机内部的工作原理有特别的了解。当你在 C 或 Ada 等高级语言中编程时,你的所有代码最终都需要转换为机器码指令,以便你的计算机可以执行它们。理解处理器在最基本级别上能做些什么的限制,也将有助于你使用高级语言进行编程。

我应该如何格式化我的代码?

[编辑 | 编辑源代码]

大多数汇编器要求汇编代码指令每行显示一条,并用回车符隔开。大多数汇编器还允许在指令、操作数等之间出现空格。你如何格式化代码完全取决于你,尽管有一些常用的方法。

一种方法是将所有内容对齐。

Label1:
mov ax, bx
add ax, bx
jmp Label3
Label2:
mov ax, cx
...

另一种方法是将所有标签放在一列,将所有指令放在另一列。

Label1: mov ax, bx
        add ax, bx
        jmp Label3
Label2: mov ax, cx
...

另一种方法是将标签放在它们自己的行上,并稍微缩进指令。

Label1:
   mov ax, bx
   add ax, bx
   jmp Label3
Label2:
   mov ax, cx
...

还有另一种方法是将标签和指令分成不同的列,并且将标签放在它们自己的行上。

Label1:
        mov ax, bx
        add ax, bx
        jmp Label3
Label2:
        mov ax, cx
...

因此有不同的方法可以做到,但有一些通用的规则是汇编程序员通常遵循的。

  1. 让你的标签一目了然,以便其他程序员可以清楚地看到它们。
  2. 更多结构(缩进)将使你的代码更易于阅读。
  3. 使用注释来解释你在做什么。一段汇编代码的含义往往并不立即明了。
华夏公益教科书