《汇编语言 基于Linux环境 3版》PDF下载

  • 购买积分:17 如何计算积分?
  • 作  者:(美)达特曼著
  • 出 版 社:北京:清华大学出版社
  • 出版年份:2014
  • ISBN:9787302345923
  • 页数:567 页
图书介绍:本书是经典汇编语言畅销书籍的最新版,美国计算机领域著名作者Jeff Duntemann的力作。作者以其渊博的专业知识,丰富的实战经验,结合生动详尽的实例,全面系统地介绍了Linux环境下如何使用汇编语言进行程序设计以及与之有关的背景知识和相关工具的使用。本书写作风格独特,采用作者最有特色的对话式风格,结合大量源于生活的暗喻,将晦涩难懂的知识点条分缕析地呈现出来,方便读者以轻松愉快的心情学习。

第1章 又一个令人愉快的星期六 1

1.1一切尽在计划之中 1

1.1.1步骤和测试 2

1.1.2不止两种方式 3

1.1.3计算机像我们一样思考 4

1.2如果这是真实情况 4

1.3此路不通,请绕行 5

1.3.1 Big Bux游戏 6

1.3.2玩Big Bux游戏 8

1.4像棋盘游戏一样的汇编语言编程 9

1.4.1代码和数据 10

1.4.2地址 11

1.4.3隐喻,将军 12

第2章 外星基数 14

2.1新数学怪物归来 14

2.2在火星上计数 15

2.2.1火星数字剖析 17

2.2.2数字基数的本质 19

2.3八进制:绿色精怪怎样偷走8和9的 19

2.4十六进制:解决数字的短缺 23

2.5从十六进制到十进制,从十进制到十六进制 27

2.5.1从十六进制到十进制 27

2.5.2从十进制到十六进制 28

2.5.3练习!练习!再练习 30

2.6十六进制运算 31

2.6.1列和进位 34

2.6.2减法和借位 34

2.6.3跨多列借位 36

2.6.4意义何在 37

2.7二进制 37

2.7.1二进制值 39

2.7.2为什么使用二进制 41

2.8二进制简写方式:十六进制 42

第3章 摘下面具 44

3.1 RAXie,我们怎么不认识你 44

3.2开关、晶体管和存储器 46

3.2.1如果走陆路,就是1 47

3.2.2晶体管开关 47

3.2.3难以置信的位缩水 49

3.2.4随机访问 51

3.2.5存储器访问时间 52

3.2.6字节,字,双字,四字 53

3.2.7精致的芯片排成一行 54

3.2.8车间工长和流水线 57

3.2.9对话内存 57

3.2.10驾驭数据总线 58

3.2.11车间工长的口袋 59

3.2.12流水线 60

3.3遵循计划行事的盒子 60

3.3.1取指和执行 61

3.3.2车间工长的内脏 62

3.3.3改变航向 64

3.4是什么vs.怎么做:体系结构和微体系结构 65

3.4.1体系结构的演变 66

3.4.2地下室里的秘密机制 67

3.5工厂经理 68

3.5.1操作系统:角落办公室 69

3.5.2 BIOS:是软件,但并不软 69

3.5.3多任务魔术 70

3.5.4内核提升 71

3.5.5内核爆炸 73

3.5.6计划 73

第4章 位置,位置,位置 74

4.1内存模式的乐趣 74

4.1.1 16位将带来64K存储空间 75

4.1.2兆字节的本质 79

4.1.3向后兼容和虚拟86模式 80

4.1.4 16位眼罩 80

4.2段的本质 81

4.2.1一个界限,而非一个位置 84

4.2.2用两个16位寄存器构成20位地址 84

4.3 16位和32位寄存器 87

4.3.1通用寄存器 88

4.3.2半寄存器 90

4.3.3指令指针寄存器 91

4.3.4标志寄存器 92

4.4三种主要的汇编编程模型 93

4.4.1实模式平面模型 93

4.4.2实模式段模型 95

4.4.3保护模式平面模型 97

4.5保护模式下不再允许我们做的事情 100

4.5.1内存映射视频系统 100

4.5.2直接访问端口硬件 101

4.5.3直接调用BIOS 102

4.6展望未来:64位“长模式” 102

第5章 汇编的权利 105

5.1文件及其包含的内容 106

5.1.1二进制文件vs.文本文件 106

5.1.2用Bless编辑器查看文件内容 108

5.1.3解释原始数据 112

5.1.4“字节序” 113

5.2文本进去,代码出来 116

5.2.1汇编语言 117

5.2.2注释 119

5.2.3当心“只写”源代码 120

5.2.4目标代码和连接器 120

5.2.5重定位能力 123

5.3汇编语言开发过程 124

5.3.1工作目录规范 125

5.3.2编辑源代码文件 126

5.3.3编译源代码文件 126

5.3.4汇编错误 127

5.3.5回到编辑器 129

5.3.6汇编警告 129

5.3.7连接目标代码文件 130

5.3.8连接错误 131

5.3.9测试.EXE文件 131

5.3.10错误vs.漏洞 132

5.3.11我们还在那里吗 133

5.3.12调试器和调试 133

5.4沿着汇编小路旅行 134

5.4.1安装软件 135

5.4.2第1步:在编辑器中编辑程序 137

5.4.3第2步:使用NASM编译程序 138

5.4.4第3步:使用LD连接器 140

5.4.5第4步:测试可执行文件 141

5.4.6第5步:在调试器中观察程序运行 142

5.4.7准备好要来真格的了吗 148

第6章 有地儿,有工具 149

6.1 Kate编辑器 151

6.1.1安装Kate编辑器 151

6.1.2启动Kate 152

6.1.3配置 154

6.1.4 Kate会话 156

6.1.5 Kate编辑器的文件管理 158

6.1.6向工具栏添加菜单项 161

6.1.7 Kate编辑器的编辑控制 162

6.1.8编程期间使用Kate编辑器 166

6.2 Linux和终端 169

6.2.1 Linux控制台 169

6.2.2 Konsole中的字符编码 170

6.2.3三个标准Unix文件 172

6.2.4 I/O重定向 173

6.2.5简易文本过滤器 175

6.2.6使用转义序列进行终端控制 177

6.2.7为什么不用汇编语言编写GUI应用程序呢 178

6.3使用Linux Make 179

6.3.1依赖条件 180

6.3.2文件何时最新 182

6.3.3依赖链 182

6.3.4从Kate编辑器内部调用Make实用工具 184

6.3.5使用touch命令强制执行生成操作 187

6.4 Insight调试器 187

6.4.1运行Insight 188

6.4.2 Insight的众多窗口 189

6.4.3快速体验Insight 190

6.4.4拿起你的工具 193

第7章 跟踪指令 194

7.1为自己建立一个沙盒 194

7.1.1一个最小的NASM程序 195

7.1.2指令及其操作数 197

7.1.3源操作数和目标操作数 197

7.1.4立即数 198

7.1.5寄存器数据 200

7.1.6内存数据 202

7.1.7混淆数据和它的地址 203

7.1.8内存数据的尺寸 204

7.1.9糟糕的过去 204

7.2 CPU的标志位 205

7.2.1标志规范 208

7.2.2使用INC指令和DEC指令加1和减1 208

7.2.3从Insight中观察标志 209

7.2.4标志如何改变程序的执行 211

7.3有符号值和无符号值 214

7.3.1补码和NEG 214

7.3.2符号扩展和MOVSX 217

7.4隐式操作数和Mul 219

7.4.1 MUL和进位标志 221

7.4.2使用DIV实现无符号除法 221

7.4.3 x86中的“慢动作”指令 223

7.5阅读和使用汇编语言参考资料 223

7.5.1对于复杂记忆的唤醒文件 224

7.5.2初学者汇编语言参考指南 224

7.5.3标志 225

7.6 NEG:求补(求补码;即,与-1相乘) 225

7.6.1合法形式 227

7.6.2操作数符号 227

7.6.3示例 228

7.6.4注解 228

7.6.5这里没有包含的内容 229

第8章 我们的崇高目标 230

8.1汇编语言程序的基本框架 230

8.1.1最开始处的注释块 232

8.1.2 .data段 233

8.1.3 .bss段 233

8.1.4 .text段 234

8.1.5标号 234

8.1.6己初始化变量 235

8.1.7字符串变量 235

8.1.8通过EQU和$推导字符串的长度 237

8.2通过堆栈实现后进先出 239

8.2.1每小时500个盘子 239

8.2.2堆栈的内容上下颠倒 241

8.2.3 Push-y指令 242

8.2.4 POP指令 244

8.2.5临时存储 246

8.3通过INT80使用Linux内核服务 247

8.3.1不中断任何事情的中断 247

8.3.2再次返回 252

8.3.3通过使用INT 80h退出一个程序 253

8.3.4软件中断VS硬件中断 254

8.3.5 INT 80h和可移植性盲目崇拜 255

8.4设计一个有价值的程序 256

8.4.1问题定义 257

8.4.2从伪代码开始 258

8.4.3连续改进 259

8.4.4不可避免的“哎呀!时刻” 263

8.4.5扫描缓冲区 264

8.4.6缓冲溢出(“Off By One”)错误 266

8.4.7进一步学习 271

第9章 位、标志、分支和表 272

9.1位就是二进制位(字节也是二进制位) 272

9.1.1位编号 273

9.1.2逻辑操作 273

9.1.3与指令 274

9.1.4位屏蔽 275

9.1.5或指令 276

9.1.6异或指令 276

9.1.7非指令 278

9.1.8段寄存器对逻辑操作没有反应 278

9.2移位操作 279

9.2.1根据什么进行移位操作 279

9.2.2移位指令的工作原理 279

9.2.3将位移入进位标志 280

9.2.4循环移位指令 280

9.2.5将己知值存入进位标志CF 282

9.3位操作 282

9.3.1将一个字节分解为两个“半字节” 285

9.3.2将高半字节移入低半字节 286

9.3.3使用查找表 286

9.3.4通过移位和相加来实现相乘 288

9.4标志、测试和分支 291

9.4.1无条件转移 292

9.4.2条件转移指令 292

9.4.3条件“缺席”时进行跳转 293

9.4.4标志 294

9.4.5通过CMP进行比较操作 295

9.4.6转移指令的错综复杂之处 296

9.4.7“大于”与“以上” 296

9.4.8使用TEST指令查找位1 298

9.4.9使用BT指令查找位0 300

9.5保护模式下内存寻址详解 301

9.5.1有效地址计算 303

9.5.2位移量 303

9.5.3基址+位移量寻址方式 304

9.5.4基址+索引寻址方式 304

9.5.5索引×缩放比例+位移量寻址方式 305

9.5.6其他寻址方式 307

9.5.7 LEA:最机密的数学机器 309

9.5.8 16位寄存器的负担 311

9.6字符表转换 312

9.6.1转换表 312

9.6.2用MOV或者XLAT进行转换 315

9.7用表来代替计算 319

第10章 分治 321

10.1盒子里面的盒子 322

10.2调用和返回 331

10.2.1调用中的调用 334

10.2.2意外递归的危险 335

10.2.3一个需要提防的标志规范Bug 336

10.2.4过程及其所需的数据 337

10.2.5保存主调程序的寄存器 338

10.2.6局部数据 341

10.2.7更多的表格技巧 342

10.2.8在过程定义中加入常量数据 344

10.3局部标号和跳转的长度 345

10.3.1“强行”访问局部标号 348

10.3.2短转移、近转移和远转移 349

10.4生成外部过程库 350

10.4.1全局声明和外部声明 351

10.4.2全局过程和外部过程的机制 353

10.4.3连接库文件到程序中 361

10.4.4太多过程和太多库的危险 362

10.5自定义过程的艺术 362

10.5.1可维护性和可重用性 363

10.5.2确定哪些代码应该成为一个过程 364

10.5.3使用注释标头 365

10.6 Linux控制台下的简单光标控制 366

10.7创建和使用宏 374

10.7.1宏定义机制 375

10.7.2定义带参数的宏 380

10.7.3宏调用机制 382

10.7.4宏内部的局部标号 383

10.7.5像包含文件一样的宏库文件 384

10.7.6宏vs.过程:优点和缺点 385

第11章 字符串奏鸣曲 387

11.1汇编语言字符串的概念 387

11.1.1彻底颠覆你的“字符串感觉” 388

11.1.2源字符串和目标字符串 388

11.1.3虚拟文本显示屏 389

11.2 REP STOSB,软件机枪 397

11.2.1机枪扫射虚拟显示器 397

11.2.2执行STOSB指令 398

11.2.3 STOSB和方向标志(DF) 399

11.2.4在显示缓冲区中定义行 400

11.2.5将缓冲区发送到Linux控制台 401

11.3半自动武器:不带REP的STOSB 401

11.3.1是谁递减了ECX 402

11.3.2 LOOP指令 402

11.3.3在屏幕上显示一个标尺 403

11.3.4 MUL并非IMUL 404

11.3.5添加ASCII数字 406

11.3.6调整AAA 408

11.3.7 Ruler过程的教训 409

11.3.8 STOS指令的16位版本和32位版本 409

11.4 MOVSB:快速块拷贝 409

11.4.1 DF和重叠块移动 411

11.4.2使用Insight单步调试REP字符串指令 413

11.5将数据存储到不连续的字符串中 414

11.5.1显示一个ASCII表 414

11.5.2嵌套指令循环 416

11.5.3当ECX变为0时进行跳转 416

11.5.4关闭内层循环 417

11.5.5关闭外层循环 418

11.5.6 Showchar小结 419

11.6命令行参数和堆栈检查 419

11.6.1两块虚拟内存 420

11.6.2 Linux堆栈剖析 422

11.6.3为什么堆栈的地址是不可预测的 424

11.6.4使用Insight设置命令行参数 424

11.6.5通过Insight的内存视图查看堆栈 425

11.7使用SCASB进行字符串搜索 427

11.7.1 REPNE v.s.REPE 431

11.7.2从堆栈中弹出,还是对堆栈寻址 432

11.7.3额外的学分 434

第12章 C语言 435

12.1什么是GNU 436

12.1.1“瑞士军刀”编译器 437

12.1.2以GNU的方式生成代码 437

12.1.3如何在汇编工作中使用gcc 439

12.1.4为什么不用gas 440

12.2连接到标准的C函数库 441

12.2.1 C调用公约 442

12.2.2建立一个框架 443

12.2.3保存和恢复寄存器 443

12.2.4建立堆栈帧 444

12.2.5销毁堆栈帧 446

12.2.6通过puts()输出字符 447

12.3使用printf()格式化文本输出 448

12.4使用fgets()和scanf()进行数据输入 452

12.5驾驭时间 459

12.5.1 C库的时间机制 459

12.5.2从系统时钟中取出time t值 461

12.5.3将time t值转换为一个格式化字符串 461

12.5.4生成单独的本地时间值 462

12.5.5通过使用MOVSD复制glibc的tm结构 463

12.6理解AT&T指令助记符 467

12.6.1 AT&T助记符公约 467

12.6.2查看gcc创建的gas源文件 468

12.6.3 AT&T内存引用语法 471

12.7产生随机数 472

12.7.1利用srand()为随机生成器“播种” 473

12.7.2产生伪随机数 474

12.7.3有些位比其他位更具随机性 479

12.7.4调用寄存器中的地址 481

12.8 C如何看待命令行参数 482

12.9简单文件输入/输出 484

12.9.1通过sscanf()将字符串转换为数字 485

12.9.2创建和打开文件 486

12.9.3使用fgets()从文件中读取文本 488

12.9.4使用fprintf()写文本到文件中 490

12.9.5关于收集过程到库中的注解 492

结论:不是结束,而是刚刚开始 501

附录A 部分x86指令集 505

附录B 字符集图 565