本书立足于目前使用为广泛的Intel x8632和x8664系列的CPU、Windows操作系统及Visual Studio 2019开发平台,从汇编语言这种直观和直接的角度,揭示计算机工作的基本原理、C语言语句和函数的处理过程、程序优化的技巧。
全书共分为19章。前5章介绍了汇编语言程序设计的基本知识,包括CPU、内存、寻址方式和常用机器指令;第6章至第11章介绍了x8632位控制台应用程序设计,包括顺序和分支、循环、子程序设计、多模块化程序设计;第12章为中断和异常处理;第13章是Win32窗口程序设计;第14章至第17章介绍了x87 FPU、MMX、SSE、AVX程序设计;第18章为x8664位汇编程序设计;第19章为上机操作。
本书内容新颖,覆盖面广,重点突出,直观易懂,趣味性强,可供各类高等院校计算机及相关专业作为教材,也可供广大使用汇编语言的工程技术人员参考。
作者从事“汇编语言程序设计”课程教学多年,为国家精品课程“汇编语言程序设计”的主要建设者之一。本书理论结合实践,符合现代教材编写思路,书中附大量代码案例,便于学生动手验证、操作。
毋庸置疑,现在的IT界很少使用汇编语言开发项目。作为一种程序设计语言,汇编语言似乎销声匿迹。这也让一些人怀疑学习汇编语言的必要性。在阅读本书后,读者完全可以打消这种疑虑了。不论是对后续课程学习、理解计算机的工作原理,还是编写高质量、高效率的应用程序,汇编语言都起着不可或缺的作用。
首先,汇编语言程序设计是计算机类专业的重要专业基础课,是从事计算机研究与应用,特别是软件研究的基础,是计算机人员必须接受的重要的专业基础训练课之一。汇编语言作为机器语言的符号表示,提供了直观、直接学习有关知识的方式。汇编程序可以看成是编译器对高级语言程序编译后的输出产物,也可以看成是在计算机上能直接加工处理的输入对象。因此,汇编语言就是连接高级语言程序和计算机硬件设备的桥梁和枢纽,为深入地理解计算机硬件、操作系统、应用程序之间的交互工作奠定基础。此外,汇编语言对于高级语言程序设计的学习和实践很有帮助。很多人在学习C/C++语言程序设计时,都会有很多疑问。例如,程序运行中为什么崩溃?程序运行中为什么会出现“莫名其妙”的结果?函数之间是如何传递参数和返回结果的?递归程序是如何运转的?为什么不返回局部变量的地址?数组越界访问会造成什么后果?指针是如何实现的?地址类型转换和数据类型转换的含义是什么?在C++程序设计中,对象构造、对象析构、继承、多态、成员对象的引用、虚函数、类模板和函数模板等是如何实现的?汇编语言是揭开高级程序设计语言工作机制神秘面纱的强有力武器。本书给出了一些C语言程序的反汇编示例,直观展现了C语言语句和函数对应的一个执行系列,进而分析变量的空间分配方法、地址类型转换、数据结构中各组成部分的空间关系、函数参数和结果的传递方法、程序执行流程的转移、递归函数的执行过程等奥秘。这些知识又助于从本质上理解程序执行过程。在编程者深刻把握语句的执行原理后,编写程序时就可以少犯错误,也可发编写出执行效率高且形式优美的程序。
其次,开发的软件运行速度快是一个常规要求。除了在“大”方面选择性能高的算法外,还需要在很多“小”方面选择快速的实现方法。在学习汇编语言后,会发现计算机指令系统提供了一些能提高程序运行性能的指令,如串操作指令、单指令多数据流指令。它们比另外一些实现相同功能的指令的速度要快得多。这也就会让人们在使用高级语言开发程序时寻找“封装”后高性能指令的函数或语句。本书在串操作和数据成组运算上给出了示例,并检测了不同实现方法的运行时间。当然,在实际项目开发中,有人直接利用汇编语言编写部分关键代码以提高系统的性能。汇编语言保持了机器语言的优点,具有直接和简捷的特点,可有效地访问、控制计算机的各种硬件设备,如磁盘、存储器、CPU、I/O端口等,且占用内存空间少,执行速度快,是高效的程序设计语言。
后,汇编语言是逆向工程、解密程序、病毒与木马分析和防治的唯一选择。在不支持高级语言开发工具的特定场合下,编写汇编程序是一种必然选择。
本书的特色之一是使用Visual Studio 2019作为汇编语言程序的开发平台。该平台操作简单,与其前辈版本Visual Studio 2010、Visual Studio 2013、Visual Studio 2017等用法相似,可以和C/C++程序开发无缝衔接,在汇编语言程序中调用C标准库函数、Windows API函数,或者在C程序中调用汇编语言编写的函数。特色之二是根据构建理论,将不同的知识关联起来形成网络,同步促进多种知识的学习。书上给出了一些大家熟悉的有代表性的C程序例子,通过研究这些例子的反汇编代码,由表及里揭示其内在的处理过程、编译技巧,进而加深对机器指令的运行过程和功能的理解,加深对计算机工作原理的理解。书中也给出了一些既用汇编语言又用C语言实现的例子,在学习汇编语言知识后,可以引导编写更高质量的C语言程序。特色之三是内容新颖、覆盖面广。本书介绍了目前使用为广泛的Intel x8632和x8664系列CPU支持指令系统,包括x8632、x87、MMX、SSE、AVX、x8664指令,以及机器指令的编码规则;介绍了Windows操作系统下控制台程序和窗口应用程序的开发;包含了多模块程序设计、C和汇编混合、C内嵌汇编、中断及异常处理程序开发、执行文件结构等内容。特色之四是趣味性强。在完成某一功能时,采用一题多解的策略,采用不同的寻址方式、不同的指令、不同的算法完成相同的任务,充分展现了编程的灵活性。同时,书上也给出了程序自我修改、机器语言编程、程序转移自主控制等特色例子。特色之五是重点突出。Intel CPU的机器指令是非常多的,可编写的程序也非常多,本书并不是指令参考书,也不是编程集锦,未纠缠于一一介绍这些指令和过多地给出程序示例,相信读者对这些知识能够举一反三,融汇贯通。建议不要死记硬背那些机器指令,将大脑降档为一个存储器。随着时间的流逝,这些指令内容都会遗忘,留在脑海里的是基本原理、基本方法和基本技巧。
在编写本书的过程中,得到了华中科技大学计算机科学与技术学院汇编语言程序设计课程组老师们的热情帮助和支持。汇编语言程序设计课程是国家级精品课程。在精品课程建设中,老师们集思广益,群策群力,使我收获颇丰。本书的编写也得到了华中科技大学出版社编辑的帮助,在此一并表示感谢
由于作者水平有限,书中错误在所难免,恳请广大读者批评指正。同时也欢迎使用本书的老师、学生和其他读者,共同探讨汇编语言的教学内容和教学方法等问题。
华中科技大学计算机科学与技术学院副教授。1991年毕业于华中科技大学计算机学院,获得软件专业硕士学位。从事数据库科研工作多年,对数据库管理系统的总体设计、并发控制、查询优化、数据库安全、并行数据库有较深的研究,在国内权威和重要期刊上发表论文20多篇。从事汇编语言程序设计、人工智能的教学工作多年,为国家精品课程“汇编语言程序设计”的主要建设者之一。
1.1什么是汇编语言(1)
1.1.1机器语言(1)
1.1.2汇编语言(2)
1.2为什么学习汇编语言(4)
1.3如何学习汇编语言(7)
1.4汇编语言源程序举例(9)
1.5计算机中信息编码的奥秘(12)
1.6使用符号的说明(14)
习题1(15)
上机实践1(16)
第2章Intel中央处理器(17)
2.1Intel公司微处理器的发展史(17)
2.2Intel x86微处理器结构(19)
2.3执 行 部 件(20)
2.3.132位CPU中的通用寄存器(21)
2.3.2通用寄存器应用示例(22)
2.4标志寄存器(23)
2.4.1条件标志位(24)
2.4.2控制标志位(26)
2.4.3系统标志位(27)
2.5指令预取部件和指令译码部件(27)
2.6分段部件和分页部件(28)
2.7x86的三种工作方式(30)
2.8Intel公司酷睿微体系结构(31)
习题2(33)
上机实践2(34)
第3章主存储器及数据在计算机内的表示形式(35)
3.1主存储器(35)
3.1.1数据存储的基本形式(35)
3.1.2数据地址的类型及转换(36)
3.2数值数据在计算机内的表示形式(37)
3.2.1有符号数和无符号数表示法(37)
3.2.2BCD码(38)
3.3字符数据在计算机内的表示形式(39)
3.4数据段定义(39)
3.4.1数据定义伪指令(40)
3.4.2表达式(40)
3.4.3汇编地址计数器(42)
3.4.4数据段定义示例(43)
3.5主存储器分段管理(44)
3.6主存储器物理地址的形成(45)
3.6.18086和x8632实方式下物理地址的形成(45)
3.6.2保护方式下物理地址的形成(47)
习题3(50)
上机实践3(51)
第4章寻址方式(53)
4.1寻址方式概述(53)
4.2立即寻址(54)
4.3寄存器寻址(56)
4.4直接寻址(57)
4.4.1直接寻址的基本概念(57)
4.4.2直接寻址的用法示例(58)
4.5寄存器间接寻址(60)
4.5.1寄存器间接寻址的基本用法(60)
4.5.2寄存器间接寻址与C语言指针的比较(62)
4.6变址寻址(63)
4.7基址加变址寻址(64)
4.8寻址方式综合举例(66)
4.9x86机器指令编码规则(68)
4.108086/80386的寻址方式(73)
习题4(74)
上机实践4(77)
第5章常用机器指令(79)
5.1通用机器指令概述(79)
5.2数据传送指令(80)
5.2.1一般数据传送指令(80)
5.2.2带条件的数据传送指令(82)
5.2.3堆栈操作指令(83)
5.2.4标志寄存器传送指令(86)
5.2.5地址传送指令(88)
5.3算术运算指令(89)
5.3.1加法指令(90)
5.3.2减法指令(91)
5.3.3乘法指令(92)
5.3.4除法指令(94)
5.3.5符号扩展指令(95)
5.4逻辑运算指令(95)
5.5移位指令(97)
5.7位操作和字节操作指令(99)
5.8标志位控制指令和杂项指令(100)
5.9I/O指令(100)
习题5(102)
上机实践5(103)
第6章顺序和分支程序设计(105)
6.1概述(105)
6.2程序中的伪指令(107)
6.2.1处理器选择伪指令(107)
6.2.2存储模型说明伪指令(108)
6.2.3段定义及程序结束伪指令(109)
6.3转移指令(110)
6.3.1转移指令概述(110)
6.3.2简单条件转移指令(110)
6.3.3无符号条件转移指令(111)
6.3.4有符号条件转移指令(113)
6.3.5无条件转移指令(114)
6.4简单分支程序设计(115)
6.4.1C语言的if语句与汇编语句的对应关系(115)
6.4.2分支程序设计示例(117)
6.4.3分支程序设计注意事项(120)
6.5多分支程序设计(121)
6.5.1多分支向无分支的转化(121)
6.5.2switch语句的编译(123)
6.6条件控制流伪指令(125)
习题6(128)
上机实践6(129)
第7章循环程序设计(131)
7.1循环程序(131)
7.1.1循环程序的结构(131)
7.1.2循环控制方法(132)
7.1.3循环控制指令(134)
7.2单重循环程序设计(137)
7.3多重循环程序设计(139)
7.4循环程序中的细节分析(141)
7.5与C循环程序反汇编的比较(145)
7.6循环控制伪指令(148)
习题7(150)
上机实践7(151)
第8章子程序设计(152)
8.1子程序的概念(152)
8.2子程序的基本用法(153)
8.2.1子程序的定义(153)
8.2.2子程序的调用和返回(154)
8.2.3在主程序与子程序之间传递参数(155)
8.2.4子程序调用现场的保护(157)
8.2.5子程序设计应注意的问题(158)
8.3子程序应用示例(159)
8.3.1字符串的比较(159)
8.3.2数串转换(161)
8.3.3串数转换(163)
8.3.4自我修改返回地址的子程序(165)
8.3.5自我修改的子程序(168)
8.4C语言程序中函数的运行机理(169)
8.5汇编语言中子程序的高级用法(172)
8.5.1局部变量的定义和使用(173)
8.5.2子程序的原型说明、定义和调用(174)
8.5.3子程序的高级用法举例(176)
8.6递归子程序的设计(177)
习题8(180)
上机实践8(181)
第9章串处理程序设计(183)
9.1串操作指令简介(183)
9.2串传送指令(185)
9.3串比较指令(187)
9.4串搜索指令(189)
9.5向目的串中存数指令(190)
9.6从源串中取数指令(191)
习题9(192)
上机实践9(192)
第10章复合数据类型的定义和使用(194)
10.1结构体(194)
10.1.1结构体的定义(194)
10.1.2结构变量的定义(195)
10.1.3结构变量的访问(196)
10.1.4结构信息的自动计算(198)
10.2结构变量的数据存储(200)
10.2.1汇编语言中结构变量的存储(200)
10.2.2与C语言结构变量存储的差异(201)
10.3联合体(202)
习题10(203)
上机实践10(203)
第11章程序设计的其他方法(205)
11.1汇编语言多模块化程序设计(205)
11.2C语言程序和汇编语言程序的混合(209)
11.2.1函数的申明和调用(209)
11.2.2变量的申明和调用(210)
11.3内嵌汇编(211)
11.4模块程序设计中的注意事项(213)
11.5宏功能程序设计(214)
11.5.1宏定义(214)
11.5.2宏调用(215)
11.5.3宏指令与子程序的比较(216)
11.6可执行文件的格式(217)
习题11(223)
上机实践11(224)
第12章中断和异常处理(225)
12.1中断与异常的基础知识(225)
12.1.1中断和异常的概念(225)
12.1.2中断描述符表(227)
12.1.3中断和异常的响应过程(229)
12.1.4软中断指令(230)
12.2Windows中的结构化异常处理(231)
12.2.1编写异常处理函数(231)
12.2.2异常处理程序的注册(232)
12.2.3全局异常处理程序的注册(234)
12.3C语言异常处理程序反汇编分析(236)
习题12(239)
上机实践12(239)
第13章Win32窗口程序设计(242)
13.1Win32窗口程序设计基础 (242)
13.1.1窗口程序运行的基本过程(242)
13.1.2Windows消息(245)
13.1.3Win32窗口程序的开发环境(247)
13.2Win32窗口应用程序的结构(248)
13.2.1主程序(248)
13.2.2窗口主程序(248)
13.2.3窗口消息处理程序(249)
13.3窗口应用程序开发实例(250)
13.3.1不含资源的窗口程序(250)
13.3.2包含菜单和对话框的窗口程序(253)
13.4与C语言开发的窗口程序比较(260)
习题13(264)
上机实践13(264)
第14章x87 FPU程序设计(265)
14.1浮点数据(265)
14.1.1浮点数据在机内的表示形式(265)
14.1.2浮点类型变量的定义(267)
14.2x87 FPU的寄存器(268)
14.2.1x87 FPU数据寄存器(268)
14.2.2x87 FPU其他寄存器(269)
14.3x87 FPU指令(271)
14.4浮点数处理程序示例(274)
习题14(277)
上机实践14(277)
第15章MMX程序设计(278)
15.1MMX技术简介(278)
15.2MMX指令简介(280)
15.3MMX编程示例(282)
15.4使用C语言编写MMX应用程序(285)
习题15(286)
上机实践15(287)
第16章SSE程序设计(288)
16.1SSE技术简介(288)
16.2SSE指令简介(289)
16.2.1组合和标量单精度浮点指令(290)
16.2.2SSE 64位SIMD整数指令(292)
16.2.3MXCSR状态管理指令(293)
16.2.4缓存控制指令(293)
16.3SSE2及后续版本的指令简介(293)
16.3.1组合双精度浮点数和标量双精度浮点数指令(294)
16.3.264位和128位整数指令(295)
16.4SSE编程示例(296)
16.5使用C语言编写SSE应用程序(297)
习题16(299)
上机实践16(300)
第17章AVX程序设计(301)
17.1AVX技术简介(301)
17.2AVX指令简介(302)
17.2.1新指令(302)
17.2.2功能扩展指令(303)
17.3AVX编程示例(304)
习题17(306)
上机实践17(306)
第18章x8664位汇编程序设计(307)
18.1x8664的运行环境(307)
18.1.1寄存器(307)
18.1.2寻址方式(308)
18.1.3指令系统(309)
18.264位的程序设计(309)
18.2.164位平台下与32位平台下的区别(309)
18.2.2显示一个消息框(312)
18.2.3浮点数运算(312)
18.2.4程序自我修改(313)
18.3x8664机器指令编码规则(314)
习题18(317)
上机实践18(317)
第19章上机操作(318)
19.1创建工程和生成可执行程序(318)
19.2程序的调试(319)
19.3编译链接器的配置(322)
19.4其他操作(324)
附录ASCII字符表(326)
参考文献(327)