汇编语言是一种什么程序设计语言?

本教程主要介绍与运行 Microsoft Windows 32 位和 64 位系统的 Intel 和 AMD 处理器相兼容的微处理器编程。

教程中使用了 Microsoft 宏汇编器(称为 MASM)的最新版本。Microsoft Visual Studio 的大多数版本(专业版,旗舰版,精简版……)都包含 MASM。

可以访问(asmirvine.com),了解 Visual Studio 对 MASM 支持的最新详细信息。同时,网站中还包括很多关于如何设置软件并开始使用的有用信息。

在运行 Microsoft Windows 的 x86 系统中,其他一些有名的汇编器包括:TASM(Turbo 汇编器),NASM(Netwide 汇编器)和 MASM32(MASM 的一种变体)。GAS(GNU 汇编器)和 NASM 是两种基于 Linux 的汇编器。在这些汇编器中,NASM 的语法与 MASM 的最相似。

汇编语言是最古老的编程语言,在所有的语言中,它与原生机器语言最为接近。它能直接访问计算机硬件,要求用户了解计算机架构和操作系统。

如果小伙伴正在学的大学课程的名称与下列课程之一相似,可以通过本教程学到更多的专业知识:
  • 微计算机汇编语言
  • 汇编语言编程
  • 计算机体系结构导论
  • 计算机系统基础
  • 嵌入式系统编程

通过本教程有助于学习计算机体系结构、机器语言和底层编程的基本原理。可以学到足够的汇编语言,来测试其掌握的当今使用最广泛的微处理器系列的知识。不会学到用模拟汇编器来编写一个“玩具”计算机;MASM 是一个由业界专业人士使用的工业级汇编器。大家将从程序员的角度来了解 Intel 处理器系列的体系结构。

如果小伙伴计划成为 C 或 C++ 开发者,就需要理解内存、地址和指令是如何在底层工作的。在高级语言层次上,很多编程错误不容易被识别。因此,程序员经常会发现需要“深入”到程序内部,才能找出程序不工作的原因。

学习汇编可能会问的问题

需要怎样的背景知识?

在学习本教程之前,至少使用过一种结构化高级语言进行编程,如 Java、C、Python 或 C++。需要了解如何使用 IF 语句、数组和函数来解决编程问题。

什么是汇编器和链接器?

汇编器(assembler)是一种工具程序,用于将汇编语言源程序转换为机器语言。链接器(linker)也是一种工具程序,它把汇编器生成的单个文件组合为一个可执行程序。还有一个相关的工具,称为调试器(debugger),使程序员可以在程序运行时,单步执行程序并检查寄存器和内存状态。

需要哪些硬件和软件?

一台运行 32 位或 64 位 Microsoft Windows 系统的计算机,并已安装了近期版本的 Microsoft Visual Studio。

MASM 能创建哪些类型的程序?

32 位保护模式(32-Bit Protected Mode):32 位保护模式程序运行于所有的 32 位和 64 位版本的 Microsoft Windows 系统。它们通常比实模式程序更容易编写和理解。从现在开始,将其简称为 32 位模式。

64 位模式(64-Bit Mode):64 位程序运行于所有的 64 位版本 Microsoft Windows 系统。

16 位实地址模式(16-Bit Real-Address Mode):16 位程序运行于 32 位版本 Windows 和嵌入式系统。 64 位 Windows 不支持这类程序。

汇编语言与机器语言有什么关系?

机器语言(machine language)是一种数字语言, 专门设计成能被计算机处理器(CPU)理解。所有 x86 处理器都理解共同的机器语言。

汇编语言(assembly language)包含用短助记符如 ADD、MOV、SUB 和 CALL 书写的语句。汇编语言与机器语言是一对一(one-to-one)的关系:每一条汇编语言指令对应一条机器语言指令。

C++ 和 Java 与汇编语言有什么关系?

高级语言如 Python、C++ 和 Java 与汇编语言和机器语言的关系是一对多(one-to-many)。比如,C++ 的一条语句就会扩展为多条汇编指令或机器指令。

大多数人无法阅读原始机器代码,因此,这里探讨的是与之最接近的汇编语言。例如,下面的 C++ 代码进行了两个算术操作,并将结果赋给一个变量。假设 X 和 Y 是 整数:
int Y;
int X = ( Y + 4 ) * 3;
与之等价的汇编语言程序如下所示。这种转换需要多条语句,因为每条汇编语句只对应一条机器指令:
mov eax,Y  ;Y 送入 EAX 寄存器
add eax,4  ;EAX 寄存器内容加 4
mov ebx,3  ;3 送入 EBX 寄存器
imul ebx   ;EAX 与 EBX 相乘
mov x,eax  ;EAX 的值送入 X
寄存器(register)是 CPU 中被命名的存储位置,用于保存操作的中间结果。这个例子的重点不是说明 C++ 与汇编语言哪个更好,而是展示它们的关系。

汇编语言可移植吗?

一种语言,如果它的源程序能够在各种各样的计算机系统中进行编译和运行,那么这种语言被称为是可移植的(portable)。

例如,一个 C++ 程序,除非需要特别引用某种操作系统的库函数,否则它就几乎可以在任何一台计算机上编译和运行。Java 语言的一大特点就是,其编译好的程序几乎能在所有计算机系统中运行。

汇编语言不是可移植的,因为它是为特定处理器系列设计的。目前广泛使用的有多种不同的汇编语言,每一种都基于一个处理器系列。

对于一些广为人知的处理器系列如 Motorola 68x00、x86、SUN Sparc、Vax 和 IBM-370,汇编语言指令会直接与该计算机体系结构相匹配,或者在执行时用一种被称为微代码解释器(microcode interpreter)的处理器内置程序来进行转换。

为什么要学习汇编语言?

如果对学习汇编语言还心存疑虑,考虑一下这些观点:
  • 如果是学习计算机工程,那么很可能会被要求写嵌入式(embedded)程序。嵌入式程序是指一些存放在专用设备中小容量存储器内的短程序,这些专用设备包括:电话、汽车燃油和点火系统、空调控制系统、安全系统、数据采集仪器、显卡、声卡、硬盘驱动器、调制解调器和打印机。由于汇编语言占用内存少,因此它是编写嵌入式程序的理想工具。
  • 处理仿真和硬件监控的实时应用程序要求精确定时和响应。高级语言不会让程序员对编译器生成的机器代码进行精确控制。汇编语言则允许程序员精确指定程序的可执行代码。
  • 电脑游戏要求软件在减少代码大小和加快执行速度方面进行高度优化。就针对一个目标系统编写能够充分利用其硬件特性的代码而言,游戏程序员都是专家。他们经常选择汇编语言作为工具,因为汇编语言允许直接访问计算机硬件,所以,为了提高速度可以对代码进行手工优化。
  • 汇编语言有助于形成对计算机硬件、操作系统和应用程序之间交互的全面理解。使用汇编语言,可以运用并检验从计算机体系结构和操作系统课程中获得的理论知识。
  • 一些高级语言对其数据表示进行了抽象,这使得它们在执行底层任务时显得有些不方便,如位控制。在这种情况下,程序员常常会调用使用汇编语言编写的子程序来完成他们的任务。
  • 硬件制造商为其销售的设备创建设备驱动程序。设备驱动程序(device driver)是一种程序,它把通用操作系统指令转换为对硬件细节的具体引用。比如,打印机制造商就为他们销售的每一种型号都创建了一种不同的 MS-Windows 设备驱动程序。通常,这些设备驱动程序包含了大量的汇编语言代码。

汇编语言有规则吗?

大多数汇编语言规则都是以目标处理器及其机器语言的物理局限性为基础的。比如,CPU 要求两个指令操作数的大小相同。与C++ 或 Java 相比,汇编语言的规则较少,因为,前者是用语法规则来减少意外的逻辑错误,而这是以限制底层数据访问为代价的。

汇编语言程序员可以很容易地绕过高级语言的限制性特征。例如,Java 就不允许访问特定的内存地址。程序员可以使用 JNI(Java Native Interface)类来调用 C 函数绕过这个限制,可结果程序不容易维护。

反之,汇编语言可以访问所有的内存地址。但这种自由的代价也很高:汇编语言程序员需要花费大量的时间进行调试。