编辑推荐
提高编程效率神器:深入理解编程底层原理,掌握优缺点,引领编程大师之路。
内容简介
本书介绍在使用高级语言编程时,程序员如何点点滴滴地提高程序运行效率,并在编写代码时,透彻地理解变量、数组、字符串、数据结构、过程与函数等方面各种方案的优缺点,从而恰当运用。书中阐述计算机编程语言在底层硬件上的工作原理,引入了一种被称为“高级汇编语言HLA”的学习工具。通过查看、比较编译器生成的汇编语言或机器代码,程序员能够了解代码的底层实现,以便在高级语言编程时选择最恰当的方式高效地达到自身的目标。本书是一部提高程序员专业能力,以及通往编程大师之路的不可多得的佳作。本书适合高等学校学生在掌握基本编程能力后,在有志于从事软件行业并精于此道时修炼使用,也可供已参加工作的程序员进一步研修、优化工作技能时参考。此外,对于有意向编写编译器的程序员,此书可提供从普通应用到底层编译的衔接,供他们学习初步的编译原理入门知识。
章节目录
封面
版权信息
内容简介
译者序
人们对《编程卓越之道(卷2):运用底层语言思想编写高级语言代码》(第1版)的赞誉之辞
关于作者
关于技术审校者
致谢
引言
1 以底层语言思考,用高级语言编程
1.1 关于编译器质量的误区
1.2 最好还是学一学汇编语言
1.3 为何学习汇编语言并非绝对必要
1.4 以底层语言思考
1.4.1 编译器生成的机器码只会与送入的源代码质量相配
1.4.2 如何协助编译器生成更好的机器码
1.4.3 在用高级语言编程时如何以汇编语言思考
1.5 编程用高级语言
1.6 不特定于某种语言的方法
1.7 附加提示
1.8 获取更多信息
2 要不要学汇编语言
2.1 学习汇编语言的好处与障碍
2.2 本书如何帮助你
2.3 向高层汇编器求援
2.4 高层汇编语言或汇编器(HLA)
2.5 以高级语言思考,用底层语言编程
2.6 汇编语言的编程范型—在底层思考
2.7 获取更多信息
3 高级语言程序员应具备的80x86汇编知识
3.1 学一种汇编语言很好,能学几种汇编语言更好
3.2 80x86汇编语言的语法
3.2.1 80x86基本架构
3.2.2 寄存器
3.2.3 80x86的32位通用寄存器
3.2.4 80x86的EFLAGS寄存器
3.3 文字常量
3.3.1 二进制文字常量
3.3.2 十进制文字常量
3.3.3 十六进制文字常量
3.3.4 字符与字符串文字常量
3.3.5 浮点型文字常量
3.4 汇编语言中的明示(符号)常量
3.4.1 HLA中的明示常量
3.4.2 Gas中的明示常量
3.4.3 MASM中的明示常量
3.5 80x86的寻址模式
3.5.1 80x86的寄存器寻址模式
3.5.2 立即寻址模式
3.5.3 位移寻址模式
3.5.4 RIP相对寻址模式
3.5.5 寄存器间接寻址模式
3.5.6 变址寻址模式
3.5.7 比例变址寻址模式
3.6 汇编语言的数据声明
3.6.1 HLA的字节数据声明
3.6.2 MASM的字节数据声明
3.6.3 Gas的字节数据声明
3.7 在汇编语言中指定操作数尺寸
3.7.1 HLA的类型强制转换
3.7.2 MASM的类型强制转换
3.7.3 Gas的类型强制转换
3.8 获取更多信息
4 编译器的操作与代码生成
4.1 编程语言所用的文件类型
4.2 编程语言的源文件
4.2.1 源文件的记号化
4.2.2 专门的源文件格式
4.3 计算机语言处理器的类型
4.3.1 纯解释器
4.3.2 解释器
4.3.3 编译器
4.3.4 增量编译器
4.4 转换过程
4.4.1 扫描(词法分析阶段)
4.4.2 分析(语法分析阶段)
4.4.3 中间代码生成阶段
4.4.4 优化
4.4.5 编译器评测
4.4.6 本机码生成
4.5 编译器的输出
4.5.1 编译器输出高级语言代码
4.5.2 编译器输出汇编语言代码
4.5.3 编译器输出目标文件
4.5.4 编译器输出可执行文件
4.6 目标文件的格式
4.6.1 COFF文件头
4.6.2 COFF可选文件头
4.6.3 COFF区域头
4.6.4 COFF区域
4.6.5 重定位区域
4.6.6 调试与符号信息
4.7 可执行文件的格式
4.7.1 页、段和文件大小
4.7.2 内部碎片
4.7.3 为什么还要空间优化
4.8 目标文件中的数据和代码对齐
4.8.1 选择区域对齐值
4.8.2 合并区域
4.8.3 区域对齐的控制
4.8.4 库模块内的区域对齐
4.9 链接器及其对代码的影响
4.10 获取更多信息
5 分析编译器输出的工具
5.1 背景知识
5.2 让编译器输出汇编语言文件
5.2.1 GNU编译器的汇编输出
5.2.2 Visual C++的汇编输出
5.2.3 汇编语言输出示例
5.2.4 分析编译器的汇编输出
5.3 通过目标码工具分析编译器的输出
5.3.1 微软的dumpbin.exe工具
5.3.2 FSF/GNU的objdump工具
5.4 通过反汇编程序分析编译器的输出
5.5 使用Java字节码反汇编程序分析Java的输出
5.6 使用IL反汇编程序分析微软C#和Visual Basic的输出
5.7 通过调试器分析编译器的输出
5.7.1 使用集成开发环境带的调试器
5.7.2 使用独立调试器
5.8 比对两次编译的输出
5.9 获取更多信息
6 常量与高级语言
6.1 文字常量与程序效率
6.2 绑定时刻
6.3 文字常量与明示常量的比较
6.4 常量表达式
6.5 明示常量与只读内存数据的比较
6.6 Swift的let语句
6.7 枚举类型
6.8 布尔常量
6.9 浮点数常量
6.10 字符串常量
6.11 复合数据类型的常量
6.12 常量值不会变化
6.13 获取更多信息
7 变量
7.1 运行时期的内存组织
7.1.1 代码、常量和只读区域
7.1.2 静态变量区域
7.1.3 变量存储区域
7.1.4 栈区域
7.1.5 堆区域与动态内存分配
7.2 变量是什么
7.2.1 属性
7.2.2 绑定
7.2.3 静态数据
7.2.4 动态数据
7.2.5 作用域
7.2.6 生命期
7.2.7 变量的定义
7.3 变量的存储
7.3.1 静态绑定与静态变量
7.3.2 伪静态绑定和自动变量
7.3.3 动态绑定与动态变量
7.4 常见的基本数据类型
7.4.1 整型变量
7.4.2 浮点型/实数变量
7.4.3 字符型变量
7.4.4 布尔变量
7.5 变量地址与高级语言
7.5.1 对全局变量和静态变量分配存储空间
7.5.2 使用自动变量减小偏移量
7.5.3 中间变量的存储空间分配
7.5.4 动态变量和指针的存储空间分配
7.5.5 使用记录/结构减小指令偏移量
7.5.6 将变量保存在寄存器里
7.6 内存中的变量对齐
7.7 获取更多信息
8 数组
8.1 何谓数组
8.1.1 数组声明
8.1.2 数组在内存中的表示
8.1.3 Swift数组的实现
8.1.4 数组元素的访问
8.1.5 填充与打包的比较
8.1.6 多维数组
8.1.7 动态数组与静态数组的比较
8.2 获取更多信息
9 指针
9.1 指针的定义
9.2 高级语言的指针实现
9.3 指针与动态内存分配
9.4 指针操作与指针算术运算
9.4.1 指针与整数求和
9.4.2 指针与整数之差
9.4.3 指针与指针之差
9.4.4 指针比较
9.4.5 指针与“与/或”逻辑运算
9.4.6 对指针的其他操作
9.5 内存分配的简单示例
9.6 垃圾收集
9.7 操作系统与内存分配
9.8 堆内存的开销
9.9 常见的指针问题
9.9.1 所用的指针未初始化
9.9.2 所用的指针含有非法值
9.9.3 释放存储空间后仍试图继续使用
9.9.4 程序用过某存储空间后却不释放
9.9.5 使用不当的数据类型访问间接数据
9.9.6 进行无效指针操作
9.10 现代编程语言中的指针
9.11 托管指针
9.12 获取更多信息
10 字符串
10.1 字符串格式
10.1.1 以0结尾的字符串
10.1.2 带长度值前缀的字符串格式
10.1.3 7位字符的字符串
10.1.4 HLA字符串格式
10.1.5 基于描述记录的字符串格式
10.2 静态字符串、伪动态字符串和动态字符串
10.2.1 静态字符串
10.2.2 伪动态字符串
10.2.3 动态字符串
10.3 字符串的引用计数
10.4 Delphi字符串格式
10.5 在高级语言中使用字符串
10.6 字符串中的Unicode字符数据
10.6.1 Unicode字符集
10.6.2 Unicode码点
10.6.3 Unicode代码平面
10.6.4 代理码点
10.6.5 字形、字符和字形集
10.6.6 Unicode规范和规范的等价性
10.6.7 Unicode编码
10.6.8 Unicode组合字符
10.7 Unicode字符串函数和性能
10.8 获取更多信息
11 记录、联合和类
11.1 记录
11.1.1 在各种语言中声明记录
11.1.2 记录的例化
11.1.3 在编译时期初始化记录数据
11.1.4 记录的内存表示
11.1.5 使用记录改善内存效能
11.1.6 使用动态记录类型和数据库
11.2 判别式联合
11.2.1 在各种语言中声明联合
11.2.2 联合的内存表示
11.2.3 联合的其他用法
11.3 变数类型
11.4 命名空间
11.5 类与对象
11.5.1 类和对象的关系
11.5.2 C++中的简单类声明
11.5.3 C#和Java的类声明
11.5.4 Delphi中的类声明
11.5.5 HLA中的类声明
11.5.6 虚方法表
11.5.7 抽象方法
11.5.8 共享虚方法表
11.5.9 类的继承
11.5.10 类的多态
11.5.11 C++中的多继承
11.6 协议与接口
11.7 类、对象和性能
11.8 获取更多信息
12 算术与逻辑表达式
12.1 算术表达式与计算机架构
12.1.1 基于栈的机器
12.1.2 基于累加器的机器
12.1.3 基于寄存器的机器
12.1.4 算术表达式的典型形式
12.1.5 三地址架构
12.1.6 双地址架构
12.1.7 架构差异和写代码的关系
12.1.8 复杂表达式的处理
12.2 算术语句的优化
12.2.1 常量折叠
12.2.2 常量传播
12.2.3 死码消除
12.2.4 公共子表达式消除
12.2.5 强度削弱
12.2.6 归纳变量
12.2.7 循环不变体
12.2.8 优化器与程序员
12.3 算术表达式的副作用
12.4 包含副作用:序列点
12.5 避免让副作用造成麻烦
12.6 强制按特定顺序计算
12.7 短路求值
12.7.1 短路求值与布尔表达式
12.7.2 强制短路布尔求值或全面布尔求值
12.7.3 短路求值和全面布尔求值的效率对比
12.8 算术运算的相对开销
12.9 获取更多信息
13 控制结构与程序判定
13.1 控制结构如何影响程序效率
13.2 底层控制结构入门
13.3 goto语句
13.4 if语句
13.4.1 提高某些if/else语句的效率
13.4.2 强制在if语句中全面布尔求值
13.4.3 强制在if语句中短路布尔求值
13.5 switch/case语句
13.5.1 switch/case语句的语义
13.5.2 跳转表与链式比较
13.5.3 switch/case语句的其他实现方案
13.5.4 Swift的switch语句
13.5.5 switch语句的编译器输出
13.6 获取更多信息
14 迭代控制结构
14.1 while循环
14.1.1 在while循环中强制全面布尔求值
14.1.2 在while循环中强制短路布尔求值
14.2 repeat..until(do..until/do..while)式的循环
14.2.1 在repeat..until循环中强制全面布尔求值
14.2.2 在repeat..until循环中强制短路布尔求值
14.3 forever..endfor式的循环
14.3.1 在forever循环中强制全面布尔求值
14.3.2 在forever循环中强制短路布尔求值
14.4 定次的for循环
14.5 获取更多信息
15 函数与过程
15.1 简单的函数与过程调用
15.1.1 保存返回地址
15.1.2 开销的其他来由
15.2 叶函数/叶过程
15.3 宏和内联函数
15.4 向函数/过程传递参数
15.5 活动记录和栈
15.5.1 活动记录的拆解
15.5.2 对局部变量指定偏移量
15.5.3 对参数指定偏移量
15.5.4 对参数和局部变量的访问
15.5.5 值要保存的寄存器
15.5.6 Java虚拟机与微软CLR的参数、局部变量
15.6 参数传递机制
15.6.1 传递值
15.6.2 传递引用
15.7 函数返回值
15.8 获取更多信息
后记:软件工程学
词汇表
网上附录
封底
编程卓越之道(卷2):运用底层语言思想编写高级语言代码(第2版)是2023年由电子工业出版社出版,作者 (美) 兰德尔·海德 (Randall Hyde) 。
得书感谢您对《编程卓越之道(卷2):运用底层语言思想编写高级语言代码(第2版)》关注和支持,如本书内容有不良信息或侵权等情形的,请联系本网站。