第一部分 指令讲解 3
第1章 CPU简介 3
1.1 指令集架构 3
第2章 最简函数 5
2.1 x86 5
2.2 ARM 5
2.3 MIPS 5
MIPS指令集与寄存器名称 6
第3章 Hello,world! 7
3.1 x86 7
3.1.1 MSVC 7
3.1.2 GCC 9
3.1.3 GCC:AT&T语体 9
3.2 x86-64 11
3.2.1 MSVC-x86-64 11
3.2.2 GCC-x86-64 12
3.3 GCC的其他特性 12
3.4 ARM 13
3.4.1 Keil 6/2013——未启用优化功能的ARM模式 14
3.4.2 Thumb模式下、未开启优化选项的Keil 15
3.4.3 ARM模式下、开启优化选项的Xcode 15
3.4.4 Thumb-2模式下、开启优化选项的Xcode(LLVM) 16
3.4.5 ARM64 18
3.5 MIPS 19
3.5.1 全局指针Global pointer 19
3.5.2 Optimizing GCC 19
3.5.3 Non-optimizing GCC 21
3.5.4 栈帧 23
3.5.5 Optimizing GCC:GDB的分析方法 23
3.6 总结 24
3.7 练习题 24
3.7.1 题目1 24
3.7.2 题目2 24
第4章 函数序言和函数尾声 25
递归调用 25
第5章 栈 26
5.1 为什么栈会逆增长 26
5.2 栈的用途 27
5.2.1 保存函数结束时的返回地址 27
5.2.2 参数传递 28
5.2.3 存储局部变量 29
5.2.4 x86:alloca()函数 29
5.2.5(Windows)SEH结构化异常处理 31
5.2.6 缓冲区溢出保护 31
5.3 典型的栈的内存存储格式 31
5.4 栈的噪音 31
5.5 练习题 34
5.5.1 题目1 34
5.5.2 题目2 34
第6章 printf()函数与参数调用 36
6.1 x86 36
6.1.1 x86:传递3个参数 36
6.1.2 x64:传递9个参数 41
6.2 ARM 44
6.2.1 ARM模式下传递3个参数 44
6.2.2 ARM模式下传递8个参数 46
6.3 MIPS 50
6.3.1 传递3个参数 50
6.3.2 传递9个参数 52
6.4 总结 56
6.5 其他 57
第7章 scanf() 58
7.1 演示案例 58
7.1.1 指针简介 58
7.1.2 x86 58
7.1.3 MSVC+OllyDbg 60
7.1.4 x64 62
7.1.5 ARM 63
7.1.6 MIPS 64
7.2 全局变量 65
7.2.1 MSVC:x86 66
7.2.2 MSVC:x86+OllyDbg 67
7.2.3 GCC:x86 68
7.2.4 MSVC:x64 68
7.2.5 ARM:Optimizing Keil 6/2013(Thumb模式) 69
7.2.6 ARM64 70
7.2.7 MIPS 70
7.3 scanf()函数的状态监测 74
7.3.1 MSVC:x86 74
7.3.2 MSVC:x86:IDA 75
7.3.3 MSVC:x86+OllyDbg 77
7.3.4 MSVC:x86+Hiew 78
7.3.5 MSVC:x64 79
7.3.6 ARM 80
7.3.7 MIPS 81
7.3.8 练习题 82
7.4 练习题 82
题目1 82
第8章 参数获取 83
8.1 x86 83
8.1.1 MSVC 83
8.1.2 MSVC+OllyDbg 84
8.1.3 GCC 84
8.2 x64 85
8.2.1 MSVC 85
8.2.2 GCC 86
8.2.3 GCC:uint64_t型参数 87
8.3 ARM 88
8.3.1 Non-optimizing Keil 6/2013(ARM mode) 88
8.3.2 Optimizing Keil 6/2013(ARM mode) 89
8.3.3 Optimizing Keil 6/2013(Thumb mode) 89
8.3.4 ARM64 89
8.4 MIPS 91
第9章 返回值 93
9.1 void型函数的返回值 93
9.2 函数返回值不被调用的情况 94
9.3 返回值为结构体型数据 94
第10章 指针 96
10.1 全局变量 96
10.2 局部变量 98
10.3 总结 100
第11章 GOTO语句 101
11.1 无用代码Dead Code 102
11.2 练习题 102
第12章 条件转移指令 103
12.1 数值比较 103
12.1.1 x86 103
12.1.2 ARM 109
12.1.3 MIPS 112
12.2 计算绝对值 115
12.2.1 Optimizing MSVC 115
12.2.2 Optimizing Keil 6/2013:Thumb mode 116
12.2.3 Optimizing Keil 6/2013:ARM mode 116
12.2.4 Non-optimizng GCC 4.9(ARM64) 116
12.2.5 MIPS 117
12.2.6 不使用转移指令 117
12.3 条件运算符 117
12.3.1 x86 117
12.3.2 ARM 118
12.3.3 ARM64 119
12.3.4 MIPS 119
12.3.5 使用if/else替代条件运算符 120
12.3.6 总结 120
12.4 比较最大值和最小值 120
12.4.1 32位 120
12.4.2 64位 123
12.4.3 MIPS 125
12.5 总结 125
12.5.1 x86 125
12.5.2 ARM 125
12.5.3 MIPS 126
12.5.4 无分支指令(非条件指令) 126
12.6 练习题 127
第13章 switch()/case/default 128
13.1 case陈述式较少的情况 128
13.1.1 x86 128
13.1.2 ARM:Optimizing Keil 6/2013(ARM mode) 133
13.1.3 ARM:Optimizing Keil 6/2013(Thumb mode) 133
13.1.4 ARM64:Non-optimizing GCC(Linaro)4.9 134
13.1.5 ARM64:Optimizing GCC(Linaro)4.9 134
13.1.6 MIPS 135
13.1.7 总结 136
13.2 case陈述式较多的情况 136
13.2.1 x86 136
13.2.2 ARM:Optimizing Keil 6/2013(ARM mode) 140
13.2.3 ARM:Optimizing Keil 6/2013(Thumb mode) 141
13.2.4 MIPS 143
13.2.5 总结 144
13.3 case从句多对一的情况 145
13.3.1 MSVC 145
13.3.2 GCC 147
13.3.3 ARM64:Optimizing GCC 4.9.1 147
13.4 Fall-through 149
13.4.1 MSVC x86 149
13.4.2 ARM64 150
13.5 练习题 151
13.5.1 题目1 151
第14章 循环 152
14.1 举例说明 152
14.1.1 x86 152
14.1.2 x86:OllyDbg 155
14.1.3 x86:跟踪调试工具tracer 156
14.1.4 ARM 157
14.1.5 MIPS 160
14.1.6 其他 161
14.2 内存块复制 161
14.2.1 编译结果 161
14.2.2 编译为ARM模式的程序 162
14.2.3 MIPS 163
14.2.4 矢量化技术 164
14.3 总结 164
14.4 练习题 165
14.4.1 题目1 165
14.4.2 题目2 165
14.4.3 题目3 166
14.4.4 题目4 167
第15章 C语言字符串的函数 170
15.1 strlen() 170
15.1.1 x86 170
15.1.2 ARM 174
15.1.3 MIPS 177
15.2 练习题 178
15.2.1 题目1 178
第16章 数学计算指令的替换 181
16.1 乘法 181
16.1.1 替换为加法运算 181
16.1.2 替换为位移运算 181
16.1.3 替换为位移、加减法的混合运算 182
16.2 除法运算 186
16.2.1 替换为位移运算 186
16.3 练习题 186
16.3.1 题目1 186
第17章 FPU 188
17.1 IEEE 754 188
17.2 x86 188
17.3 ARM、MIPD、x86/x64 SIMD 188
17.4 C/C++ 188
17.5 举例说明 189
17.5.1 x86 189
17.5.2 ARM:Optimizing Xcode 4.6.3(LLVM)(ARM mode) 193
17.5.3 ARM:Optimizing Keil 6/2013(Thumb mode) 193
17.5.4 ARM64:Optimizing GCC(Linaro)4.9 194
17.5.5 ARM64:Non-optimizing GCC(Linaro)4.9 195
17.5.6 MIPS 195
17.6 利用参数传递浮点型数据 196
17.6.1 x86 196
17.6.2 ARM+Non-optimizing Xcode 4.6.3(LLVM)(Thumb-2 mode) 197
17.6.3 ARM+Non-optimizing Keil 6/2013(ARM mode) 198
17.6.4 ARM64+Optimizing GCC(Linaro)4.9 198
17.6.5 MIPS 199
17.7 比较说明 200
17.7.1 x86 200
17.7.2 ARM 216
17.7.3 ARM64 219
17.7.4 MIPS 220
17.8 栈、计算器及逆波兰表示法 221
17.9 x64 221
17.10 练习题 221
17.10.1 题目1 221
17.10.2 题目2 221
第18章 数组 223
18.1 简介 223
18.1.1 x86 223
18.1.2 ARM 225
18.1.3 MIPS 228
18.2 缓冲区溢出 229
18.2.1 读取数组边界以外的内容 229
18.2.2 向数组边界之外的地址赋值 231
18.3 缓冲区溢出的保护方法 234
18.3.1 Optimizing Xcode 4.6.3(LLVM)(Thumb-2 mode) 236
18.4 其他 238
18.5 字符串指针 238
18.5.1 x64 239
18.5.2 32位MSVC 239
18.5.3 32位ARM 240
18.5.4 ARM64 241
18.5.5 MIPS 242
18.5.6 数组溢出 242
18.6 多维数组 245
18.6.1 二维数组举例 246
18.6.2 以一维数组的方式访问二维数组 247
18.6.3 三维数组 248
18.6.4 更多案例 251
18.7 二维字符串数组的封装格式 251
18.7.1 32位ARM 253
18.7.2 ARM64 254
18.7.3 MIPS 254
18.7.4 总结 255
18.8 本章小结 255
18.9 练习题 255
18.9.1 题目1 255
18.9.2 题目2 258
18.9.3 题目3 263
18.9.4 题目4 264
18.9.5 题目5 265
第19章 位操作 270
19.1 特定位 270
19.1.1 x86 270
19.1.2 ARM 272
19.2 设置/清除特定位 274
19.2.1 x86 274
19.2.2 ARM+Optimizing Keil 6/2013(ARM mode) 277
19.2.3 ARM+Optimizing Keil 6/2013(Thumb mode) 278
19.2.4 ARM+Optimizing Xcode(LLVM)+ARM mode 278
19.2.5 ARM:BIC指令详解 278
19.2.6 ARM64:Optimizing GCC(Linaro)4.9 278
19.2.7 ARM64:Non-optimizing GCC(Linaro)4.9 279
19.2.8 MIPS 279
19.3 位移 279
19.4 在FPU上设置特定位 279
19.4.1 XOR操作详解 280
19.4.2 x86 280
19.4.3 MIPS 282
19.4.4 ARM 282
19.5 位校验 284
19.5.1 x86 286
19.5.2 x64 289
19.5.3 ARM+Optimizing Xcode 4.6.3(LLVM)+ARM mode 291
19.5.4 ARM+Optimizing Xcode 4.6.3(LLVM)+Thumb-2 mode 292
19.5.5 ARM64+Optimizing GCC 4.9 292
19.5.6 ARM64+Non-optimizing GCC 4.9 292
19.5.7 MIPS 293
19.6 本章小结 295
19.6.1 检测特定位(编译阶段) 295
19.6.2 检测特定位(runtime阶段) 295
19.6.3 设置特定位(编译阶段) 296
19.6.4 设置特定位(runtime阶段) 296
19.6.5 清除特定位(编译阶段) 296
19.6.6 清除特定位(runtime阶段) 297
19.7 练习题 297
19.7.1 题目1 297
19.7.2 题目2 298
19.7.3 题目3 301
19.7.4 题目4 301
第20章 线性同余法与伪随机函数 304
20.1 x86 304
20.2 x64 305
20.3 32位ARM 306
20.4 MIPS 306
MIPS的重新定位 307
20.5 本例的线程安全改进版 309
第21章 结构体 310
21.1 MSVC:systemtime 310
21.1.1 OllyDbg 311
21.1.2 以数组替代结构体 312
21.2 用malloc()分配结构体的空间 313
21.3 UNIX:struct tm 315
21.3.1 Linux 315
21.3.2 ARM 317
21.3.3 MIPS 319
21.3.4 数组替代法 320
21.3.5 替换为32位words 322
21.3.6 替换为字节型数组 323
21.4 结构体的字段封装 325
21.4.1 x86 325
21.4.2 ARM 329
21.4.3 MIPS 330
21.4.4 其他 331
21.5 结构体的嵌套 331
OllyDbg 332
21.6 结构体中的位操作 333
21.6.1 CPUID 333
21.6.2 用结构体构建浮点数 337
21.7 练习题 339
21.7.1 题目1 339
21.7.2 题目2 340
第22章 共用体(union)类型 345
22.1 伪随机数生成程序 345
22.1.1 x86 346
22.1.2 MIPS 347
22.1.3 ARM(ARM mode) 348
22.2 计算机器精度 349
22.2.1 x86 350
22.2.2 ARM64 350
22.2.3 MIPS 351
22.2.4 本章小结 351
22.3 快速平方根计算 351
第23章 函数指针 352
23.1 MSVC 353
23.1.1 MSVC+OllyDbg 354
23.1.2 MSVC+tracer 355
23.1.3 MSVC+tracer(指令分析) 356
23.2 GCC 357
23.2.1 GCC+GDB(有源代码的情况) 358
23.2.2 GCC+GDB(没有源代码的情况) 359
第24章 32位系统处理64位数据 362
24.1 64位返回值 362
24.1.1 x86 362
24.1.2 ARM 362
24.1.3 MIPS 362
24.2 参数传递及加减运算 363
24.2.1 x86 363
24.2.2 ARM 365
24.2.3 MIPS 365
24.3 乘法和除法运算 366
24.3.1 x86 367
24.3.2 ARM 368
24.3.3 MIPS 369
24.4 右移 370
24.4.1 x86 370
24.4.2 ARM 371
24.4.3 MIPS 371
24.5 32位数据转换为64位数据 371
24.5.1 x86 372
24.5.2 ARM 372
24.5.3 MIPS 372
第25章 SIMD 373
25.1 矢量化 373
25.1.1 用于加法计算 374
25.1.2 用于内存复制 379
25.2 SIMD实现strlen() 383
第26章 64位平台 387
26.1 x86-64 387
26.2 ARM 394
26.3 浮点数 394
第27章 SIMD与浮点数的并行运算 395
27.1 样板程序 395
27.1.1 x64 395
27.1.2 x86 396
27.2 传递浮点型参数 399
27.3 浮点数之间的比较 400
27.3.1 x64 400
27.3.2 x86 401
27.4 机器精 402
27.5 伪随机数生成程序(续) 402
27.6 总结 403
第28章 ARM指令详解 404
28.1 立即数标识(#) 404
28.2 变址寻址 404
28.3 常量赋值 405
28.3.1 32位ARM 405
28.3.2 ARM64 405
28.4 重定位 406
第29章 MIPS的特点 409
29.1 加载常量 409
29.2 阅读推荐 409
第二部分 硬件基础 413
第30章 有符号数的表示方法 413
第31章 字节序 415
31.1 大端字节序 415
31.2 小端字节序 415
31.3 举例说明 415
31.4 双模二元数据格式 416
31.5 转换字节序 416
第32章 内存布局 417
第33章 CPU 418
33.1 分支预测 418
33.2 数据相关性 418
第34章 哈希函数 419
单向函数与不可逆算法 419
第三部分 一些高级的例子 423
第35章 温度转换 423
35.1 整数值 423
35.1.1 x86构架下MSVC 2012优化 423
35.1.2 x64构架下的MSVC 2012优化 425
35.2 浮点数运算 425
第36章 斐波拉契数列 428
36.1 例子1 428
36.2 例子2 430
36.3 总结 433
第37章 CRC32计算的例子 434
第38章 网络地址计算实例 437
38.1 计算网络地址函数calc_network_address() 438
38.2 函数form_IP() 439
38.3 函数print_as_IP() 440
38.4 form_netmask()函数和set_bit()函数 442
38.5 总结 442
第39章 循环:几个迭代 444
39.1 三个迭代器 444
39.2 两个迭代器 445
39.3 Intel C++2011实例 446
第40章 达夫装置 449
第41章 除以9 452
41.1 x86 452
41.2 ARM 453
41.2.1 ARM模式下,采用Xcode 4.6.3(LLVM)优化 453
41.2.2 Thumb-2模式下的Xcode 4.6.3 优化(LLVM) 454
41.2.3 非优化的Xcode 4.6.3(LLVM)以及Keil 6/2013 454
41.3 MIPS 454
41.4 它是如何工作的 455
41.4.1 更多的理论 456
41.5 计算除数 456
41.5.1 变位系数#1 456
41.5.2 变位系数#2 457
41.6 练习题 458
第42章 字符串转换成数字,函数atoi() 459
42.1 例1 459
42.1.1 64位下的MSVC 2013优化 459
42.1.2 64位下的GCC 4.9.1 优化 460
42.1.3 ARM模式下Keil 6/2013优化 460
42.1.4 Thumb模式下Keil 6/2013优化 461
42.1.5 ARM64下的GCC 4.9.1优化 462
42.2 例2 462
42.2.1 64位下的GCC 4.9.1优化 463
42.2.2 ARM模式下的Keil 6/2013优化 464
42.3 练习题 465
第43章 内联函数 466
43.1 字符串和内存操作函数 467
43.1.1 字符串比较函数strcmp() 467
43.1.2 字符串长度函数strlen() 469
43.1.3 字符串复制函数strcpy() 469
43.1.4 内存设置函数memset() 470
43.1.5 内存复制函数memcpy() 471
43.1.6 内存对比函数memcmp() 473
43.1.7 IDA脚本 474
第44章 C99标准的受限指针 475
第45章 打造无分支的abs()函数 478
45.1 x64下的GCC 4.9.1优化 478
45.2 ARM64下的GCC 4.9优化 478
第46章 变长参数函数 480
46.1 计算算术平均值 480
46.1.1 cdecl调用规范 480
46.1.2 基于寄存器的调用规范 481
46.2 vprintf()函数例子 483