前言
本书是作者30年工作的结晶。本书最早的版本是作者在加州理工大学波莫纳分校和加州大学河滨分校提供给学生的课堂笔记,标题是“如何使用8088汇编语言为IBM PC编程”。学生们和作者的一个好朋友玛丽·菲利普斯(Mary Philips)提出了很多宝贵的意见。比尔·波洛克(Bill Pollock)最先在互联网上发现了课堂笔记的早期版本,并在卡罗尔·朱拉多(Karol Jurado)的帮助下,使The Art of Assembly Language第1版于2003年正式出版。
后来,基于数以千计读者的意见和反馈,以及在No Starch出版社的比尔·波洛克(Bill Pollock)、艾莉森·彼得森(Alison Peterson)、安塞尔·斯塔顿(Ansel Staton)、莱利·霍夫曼(Riley Hoffman)、梅根·邓查克(Megan Dunchak)、琳达·雷克滕瓦尔德(Linda Recktenwald)、苏珊·格利纳特·史蒂文斯(Susan Glinert Stevens)、南希·贝尔(Nancy Bell)和技术审稿人内森·贝克(Nathan Baker)的支持下,The Art of Assembly Language的第2版于2010年出版。
转眼十年过去了,The Art of Assembly Language(作者将其简称为AoA)渐渐失去了流行度,因为该书所阐述的内容与英特尔x86的35年前的32位设计紧密关联。今天,打算学习80x86汇编语言的人可能想学习在较新的x86-64 CPU上的64位汇编语言。因此,鉴于32位的AoA基于HLA,在2020年年初,作者即开始使用MASM,逐步将陈旧的32位AoA转换为64位的。
刚开始着手这个将AoA从32位转为64位的项目时,作者曾天真地认为只需要把少量HLA程序翻译成MASM,调整一些文本,花费少量的精力即可。结果证明作者的想法大错特错。No Starch出版社的工作人员希望在可读性和易理解性方面取得突破,托尼·特里贝利(Tony Tribelli)在对这本书中的每一行文本和代码进行技术审查时所做的工作令人难以置信。因此,这个从32位到64位转换项目的工作相当于从头开始撰写一本新书。不过至少所有的努力都是值得的,相信读者能从我们辛勤编撰的成果中有所领悟。
关于本书中所提供的源代码
本书中包含了大量的x86-64汇编语言(以及C/C++语言)源代码。通常情况下,源代码有三种形式,即代码片段(code snippet)、单一汇编语言过程或函数(single assembly language procedure or function)以及完整程序(full-blown program)。
代码片段是程序的片段。代码片段不是独立的程序,并且不能使用MASM进行编译或汇编(如果是C/C++源代码,则不能使用C/C++编译器编译这些代码片段)。本书中之所以使用代码片段,是为了说明一个观点或提供一个编程技术的小例子。本书中代码片段的典型示例如下:
someConst=5
.
.
.
mov eax,someConst
垂直省略号表示可能出现在其位置的任意代码(需要注意的是,并非所有代码片段都使用垂直省略号)。
汇编语言过程或函数也不是独立的程序。虽然读者可以对本书中出现的许多汇编语言过程加以汇编(只需将本书中的代码直接复制到编辑器中,然后在生成的文本文件上运行MASM),但这些过程并不会自行执行。代码片段和汇编语言过程的主要区别在于:汇编语言过程包含在本书可下载的源文件中(下载网址为https://artofasm.randallhyde.com/)。
在本书中,可以编译和执行的完整程序被标记为程序清单(listing),它有“程序清单C-N”形式的编号或标识符,其中C是章编号,N是顺序递增的程序清单编号,每章中编号N从1开始。以下是本书中出现的程序清单示例。
程序清单1-3 MASM程序(listing1-3.asm文件),被程序清单1-2中的C++程序调用
;程序清单1-3
;一个简单的MASM模块,包含一个空函数,被程序清单1-2中的C++代码调用。
.CODE
;(有关option伪指令的说明,请参见后续正文。)
option casemap:none
;以下是“asmFunc”函数的定义。
public asmFunc
asmFunc PROC
;空函数,直接返回到C++代码。
ret;返回到调用方
asmFunc ENDP
END
与汇编语言过程一样,在作者的网站(https://artofasm.randallhyde.com/)上也可以找到本书所有的程序清单。该网站包含了本书所有源代码文件以及相关资源信息(例如勘误表、电子版和其他有用信息)的页面。为了便于阅读,有几个章节将程序清单编号附加到过程和宏上,这些过程和宏不是完整的程序。有些程序清单只用来演示MASM的语法错误,因此无法运行。源代码发行包中仍然包含这些程序清单的源代码,代码名称为对应的程序清单名。
通常情况下,本书使用build命令和示例输出跟踪可执行的程序清单。以下是一个典型示例(用户输入内容以黑体字的形式给出):
C:\>build listing4-7
C:\>echo off
Assembling:listing4-7.asm
c.cpp
C:\>listing4-7
Calling Listing 4-7:
aString:maxLen:20,len:20,string data:'Initial String Data'
Listing 4-7 terminated
本书中的大多数程序是从Windows命令行(即在cmd.exe应用程序中)运行的。默认情况下,本书假定读者从C:驱动器的根目录下运行程序。因此,对于每个build命令和示例输出,通常在用户使用键盘往命令行键入的任何命令之前都有文本前缀C:\>。当然,读者可以在任何驱动器或目录下运行程序。
如果读者完全不熟悉Windows命令行,那么建议花一点时间了解一下Windows命令行解释器(command line interpreter,CLI)。可以通过Windows的run命令执行cmd.exe来启动CLI。在阅读本书时,读者将需要经常运行CLI,因此建议读者在计算机桌面上创建cmd.exe的快捷方式。在附录A中,作者描述了如何在计算机的桌面上创建这个快捷方式,以自动设置轻松运行MASM(以及微软Visual C++编译器)所需的环境变量。