第六章 Turbo Assembler与Turbo C的接口 1
6.1 在Turbo C中使用嵌入式汇编 1
6.1.1 嵌入式汇编如何工作 3
6.1.1.1 Turbo C如何知道使用嵌入式汇编模式 6
6.1.1.2 激活Turbo Assembler处理嵌入式汇编 7
6.1.1.3 Turbo C在何处汇编嵌入式汇编码 7
6.1.1.4 将-L开关用于80186/80286指令 8
6.1.2 嵌入式汇编语句的格式 9
6.1.2.1 嵌入式汇编中的分号 9
6.1.2.2 嵌入式汇编中的注解 9
6.1.2.3 访问结构/联合的元素 10
6.1.3 嵌入式汇编示例 12
6.1.4 嵌入式汇编的限制 15
6.1.4.1 内存和地址操作数限制 15
6.1.4.2 嵌入式汇编中缺少隐含的自动变量大小 16
6.1.4.3 必须保存寄存器 18
6.1.4.3.1 保存调用函数和寄存器变量 18
6.1.4.3.2 抑制内部寄存器变量 18
6.1.5 嵌入式汇编码相对于纯C代码缺点 18
6.1.5.1 降低了可移植性和可维护性 18
6.1.5.2 降低了编译速度 18
6.1.5.3 仅可由TCC使用 19
6.1.5.4 损失了优化能力 19
6.1.5.5 限制了对错误的反跟踪 19
6.1.5.6 调试限制 19
6.1.5.7 用C开发而用嵌入式汇编编译最终代码 20
6.2 在Turbo C中调用Turbo Assembler函数 20
6.2.1 Turbo C与Turbo Assembler的接口机制 21
6.2.1.1 内存模式和段 21
6.2.1.1.1 简化的段伪指令与Turbo C 21
6.2.1.1.2 过时风格的段伪指令与Turbo C 23
6.2.1.1.3 段缺省:何时需要装载段? 25
6.2.1.2 公共量和外部量 28
6.2.1.2.1 下划线 28
6.2.1.2.2 大小写字母的意义 29
6.2.1.2.3 标号类型 29
6.2.1.2.4 远类型的外部量必须在任何段之外 30
6.2.1.3 链接器命令行 32
6.2.2 Turbo Assembler与Turbo C的交互性 32
6.2.2.1 参数传递 32
6.2.2.2 保存寄存器 38
6.2.2.3 返回值 39
6.2.3 从Turbo C中调用Turbo Assembler函数 40
6.2.4 Pascal调用约定 43
6.3 在Turbo Assembler中调用Turbo C 44
6.3.1 链入C的启动码 44
6.3.2 确保已正确设置了段 45
6.3.3 执行调用 45
6.3.4 在Turbo Assembler调用Turbo C函数 46
第七章 Turbo Assembler与Turbo Pascal的接口 49
7.1 Turbo Pascal内存映象 49
7.1.1 程序段前缀 49
7.1.2 代码段 49
7.1.3 全局数据段 50
7.1.4 堆栈 50
7.1.5 堆 51
7.2 Turbo Pascal中寄存器的用法 51
7.3 近调用还是远调用? 51
7.4 与Turbo Pascal共享信息 51
7.4.1 $L编译伪指令和外部子程序 51
7.4.2 PUBLIC伪指令:使Turbo Pascal可利用Turbo Assembler的信息 52
7.4.3 EXTRN伪指令:使Turbo assembler可利用Turbo Assembler的信息 53
7.4.3.1 使用EXTRN对象的限制 55
7.4.4 使用段定位 56
7.4.5 无效代码的消除 56
7.5 Turbo Pascal参数传递约定 56
7.5.1 值参 56
7.5.1.1 标量类型 57
7.5.1.2 实型 57
7.5.1.3 单精度、双精度、扩展的和复合型:8087类型 57
7.5.1.4 指针 57
7.5.1.5 串 57
7.5.1.6 记录和数组 57
7.5.1.7 集合 57
7.5.2 变量参数 58
7.5.3 栈的维护 58
7.5.4 存取参数 58
7.5.4.1 使用BP寄存器寻址堆栈 58
7.5.4.1.1 ARG伪指令 59
7.5.4.1.2 .MODEL和Turbo Pascal 60
7.5.4.1.3 使用另一个基址或变址寄存器 60
7.6 Turbo Pascal中的函数结果 61
7.6.1 标量函数结果 61
7.6.2 实型函数结果 61
7.6.3 8087函数结果 61
7.6.4 串函数结果 61
7.6.5 指针函数结果 61
7.7 为局部数据分配空间 61
7.7.1 分配私有静态存贮区 61
7.7.2 分配动态存贮区 62
7.8 由Turbo Pascal调用汇编语言子程的例子 63
7.8.1 通用十六进制转换子程序 63
7.8.2 交换两个变量 66
7.8.3 扫描DOS环境 69
第八章 Turbo Assembler与Turbo Basic的接口 74
8.1 传递参数 74
8.1.1 不在当前数据段的变量 76
8.1.2 什么类型的调用? 76
8.2 弹出堆栈 76
8.3 为Turbo Basic创建一个汇编程序 77
8.4 调用一个在线汇编子程序 77
8.5 在内存中安装一个Turbo Basic子程序 79
8.5.1 隐藏串 80
8.5.2 绝对调用(CALL ABSOLUTE) 81
8.5.2.1 到一固定内存位置作CALL ABSOLUTE 81
8.5.2.2 到内存不定位置作CALL ABSOLUTE 82
8.5.2.3 CALL ABSOLUTE的其它问题 83
8.6 调用中断 83
8.7 样本程序 84
第九章 Turbo Assembler与Turbo Prolog的接口 87
9.1 声明外部谓词 87
9.2 调用约定和参数 87
9.2.1 命名约定 88
9.3 写汇编语言谓词 88
9.3.1 实现double谓词 91
9.4 用多重流模式实现谓词 93
9.5 从汇编函数调用Turbo Prolog谓词 95
9.5.1 表和函子 97
第十章 Turbo Assembler高级程序设计 101
10.1 段前缀 101
10.1.1 一种可选形式 102
10.1.2 在什么情况下段前缀并不起作用 103
10.1.3 访问多个段 104
10.2 局部标号 105
10.3 自动确定转移大小 108
10.4 超前引用代码和数据 113
10.5 使用重复块和宏 116
10.5.1 重复块 116
10.5.1.1 重复块和可变参数 119
10.5.2 宏 120
10.5.2.1 嵌套宏 124
10.5.2.2 宏与条件句 125
10.5.2.3 用EXITM终止扩展 126
10.5.2.4 在宏内定义标号 127
10.6 良好的数据结构 128
10.6.1 STRUC伪指令 129
10.6.1.1 使用STRUC的好处和坏处 132
10.6.1.1.1 结构域名维一 133
10.6.1.1.2 嵌套结构 133
10.6.1.1.3 结构初始化 134
10.6.2 RECORD伪指令 136
10.6.2.1 访问记录 137
10.6.2.1.1 WIDTH算子 139
10.6.2.1.2 MASK算子 139
10.6.2.2 为什么要使用记录 140
10.6.3 UNION伪指令 142
10.7 段伪指令 145
10.7.1 SEGMENT伪指令 145
10.7.1.1 name和align域 146
10.7.1.2 combine域 146
10.7.1.3 use和class域 147
10.7.1.4 段长度、段类型、段名和段嵌套 147
10.7.2 段排序 149
10.7.3 GROUP伪指令 150
10.7.4 ASSUME伪指令 152
10.7.5 简化的段伪指令 156
10.7.6 多段程序示例 160
第十一章 80386及其它处理器 165
11.1 用汇编语言代码切换处理器类型 165
11.2 80186和80188 166
11.2.1 启动80186汇编 166
11.2.2 新增伪指令 166
11.2.2.1 PUSHA和POPA 166
11.2.2.2 ENTER和LEAVE 167
11.2.2.3 BOUND 168
11.2.2.4 INS和OUTS 169
11.2.3 8086指令的扩展形式 170
11.2.3.1 压入立即数 170
11.2.3.2 移位量和循环量可以是立即数 170
11.2.3.3 乘以立即数 171
11.3 80286 172
11.3.1 启动80286汇编 172
11.4 80386 173
11.4.1 选择80386汇编模式 173
11.4.2 新增段类型 173
11.4.2.1 简化的段伪指令和80386段类型 177
11.4.2.2 48位数据类型FWORD 178
11.4.3 新增寄存器 180
11.4.3.1 32位通用寄存器 180
11.4.3.2 32位标志寄存器 182
11.4.3.3 32位指令指针 182
11.4.3.4 新段寄存器 183
11.4.4 新的寻址方式 185
11.4.5 新增加的指令 189
11.4.5.1 位测试 189
11.4.5.2 位扫描 190
11.4.5.3 带符号扩展或零扩展的数据移动 191
11.4.5.4 转换成双字或四倍字数据 192
11.4.5.5 多字移位 192
11.4.5.6 条件设置字节 194
11.4.5.7 装配SS、FS和GS 194
11.4.6 扩展指令 195
11.4.6.1 特殊版本的MOV指令 196
11.4.6.2 32位版本的8086指令 197
11.4.6.2.1 新版本的LOOP和JCXZ 197
11.4.6.2.2 新版本的串指令 198
11.4.6.2.3 IRETD 199
11.4.6.2.4 PUSHFD和POPFD 199
11.4.6.2.5 PUSHAD和POPAD 199
11.4.6.2 新版本的IMUL 199
11.4.7 混合使用16和32位指令和段 200
11.4.8 80386函数示例 202
11.5 80287 207
11.6 80387 207
第十二章 Turbo Assembler中的Ideal模式 208
12.1 什么是Ideal模式? 208
12.2 为什么要使用Ideal模式? 208
12.3 进入和退出Ideal模式 209
12.4 MASM模式与Ideal模式之间的区别 210
12.4.1 Ideal模式下的标记符 210
12.4.1.1 符号标记符 210
12.4.1.2 重复成员名 211
12.4.1.3 浮点数标记符 211
12.4.2 正文等价符和数字等价符(EQU和=伪指令) 211
12.4.3 表达式和操作数 212
12.4.3.1 在方括号[]算子 212
12.4.3.2 操作数示例 212
12.4.4 算符 214
12.4.4.1 结构成员中的句号 214
12.4.4.2 结构指针 214
12.4.4.3 SYMTYPE算子 214
12.4.4.4 HIGH算子和LOW算子 214
12.4.4.5 可选的PTR算子 215
12.4.4.6 SIZE算子 215
12.4.5 伪指令 216
12.4.5.1 列表控制符 216
12.4.5.2 以句点(.)开始的伪指令 217
12.4.5.3 伪指令名与符号名的反序 217
12.4.5.4 作为伪指令参量的引用串 218
12.4.6 段和段组 218
12.4.6.1 访问属于段组的段中的数据 219
12.4.7 定义近代码标号或远代码标号 220
12.4.8 外部符号、公用符号和全程符号 221
12.4.9 其它方面的区别 222
12.4.9.1 抑制定位 222
12.4.9.2 BOUND指令的操作数 222
12.4.9.3 宏内的注释 222
12.4.9.4 局部符号 223
12.5 MASM模式与Ideal模式下程序设计的对比 223
12.5.1 MASM模式下的程序示例 223
12.5.2 Ideal模式下的程序示例 224
12.5.3 对MASM模式和Ideal模式的剖析 226