欢迎光临澳大利亚新华书店网 [登录 | 免费注册]

    • Linux x64汇编语言编程
      • 作者:(美)杰夫·邓特曼|责编:王军|译者:贾玉彬//王文杰
      • 出版社:清华大学
      • ISBN:9787302686415
      • 出版日期:2025/06/01
      • 页数:446
    • 售价:63.2
  • 内容大纲

        本书介绍二进制、十六进制、计算、编程和x64架构的基础知识,分析Linux软件开发过程,讲解NASM汇编器、x64指令集、内存寻址、过程、宏及Linux的C库函数接口,披露软件设计、编码、测试和调试的实用技巧。本书示例代码丰富,文笔幽默,将深奥的知识讲得简单易懂,引导你循序渐进地学会汇编编程。
        本书是权威的Intel/AMD x64教程,是学习x64汇编语言的黄金标准,非常适合自学。
  • 作者介绍

        杰夫·邓特曼(Jeff Duntemann),是一位在科幻文学与技术领域皆有建树的知名作家,发表技术文章逾百篇;现为技术出版顾问兼Copperwood Press独立出版人。Jeff迄今已撰写20本技术书籍。Jeff曾在Dr.Dobb's Journal杂志撰写“结构化编程”专栏达四年之久,并在其他杂志上发表了数十篇技术文章。其作品以技术深度与叙事魅力的完美融合著称。
  • 目录

    第1章  一切都在计划之中——真正理解计算机的工作原理
      1.1  完美的周六计划
        1.1.1  步骤和测试
        1.1.2  决定总是具有二元性
        1.1.3  计算机像我们一样思考
      1.2  如果这是真的
      1.3  将汇编语言编程比作方块舞
      1.4  将汇编语言编程比作棋盘游戏
        1.4.1  代码和数据
        1.4.2  地址
        1.4.3  总结
    第2章  外星人基地——理解二进制和十六进制
      2.1  新数学怪兽的回归
        2.1.1  使用火星文计数
        2.1.2  剖析火星数字
        2.1.3  数基的本质
      2.2  八进制:鬼精灵如何偷走8和
      2.3  十六进制:解决数字短缺问题
      2.4  从十六进制到十进制以及从十进制到十六进制
        2.4.1  从十六进制到十进制
        2.4.2  从十进制到十六进制
      2.5  练习!练习!练习!
      2.6  十六进制算术
        2.6.1  列和进位
        2.6.2  减法和借位
        2.6.3  跨多列借位
        2.6.4  重点是什么?
      2.7  二进制
        2.7.1  二进制值
        2.7.2  为什么是二进制
      2.8  十六进制作为二进制的简写
      2.9  准备计算
    第3章  揭开面纱——了解计算机的真实面貌
      3.1  RAX寄存器,我们几乎不了解
      3.2  开关、晶体管和内存
        3.2.1  如果敌方陆路来袭,则点亮一盏灯
        3.2.2  晶体管开关
        3.2.3  令人难以置信的比特缩小现象
        3.2.4  随机访问
        3.2.5  内存访问时间
        3.2.6  字节、字、双字和四字
        3.2.7  排成一排的精美芯片
      3.3  CPU和装配线
        3.3.1  与内存对话
        3.3.2  搭乘数据总线
        3.3.3  寄存器
        3.3.4  装配线
      3.4  遵循计划的盒子
        3.4.1  获取并执行
        3.4.2  CPU的内部结构

        3.4.3  改变路线
      3.5  什么与如何:架构和微架构
        3.5.1  不断演变的架构
        3.5.2  地下室的秘密机器
      3.6  工厂经理
        3.6.1  操作系统:转角办公室
        3.6.2  BIOS:软件不“软”
        3.6.3  多任务魔法
        3.6.4  提升至内核
        3.6.5  内核爆炸
        3.6.6  计划
    第4章  寻址、寻址、寻址——寄存器、内存寻址及了解数据的位置
      4.1  内存模型的乐趣
        4.1.11  6位能“买到”64KB
        4.1.2  兆字节(MB)的本质
        4.1.3  向后兼容和虚拟86模式
        4.1.41  6位的视野限制
      4.2  分段的本质
        4.2.1  一条地平线,而不是一个具体位置
        4.2.2  使用16位寄存器生成20位地址
      4.3  分段寄存器
        4.3.1  分段寄存器和x
        4.3.2  通用寄存器
        4.3.3  寄存器的高位和低位
        4.3.4  指令指针
        4.3.5  标志寄存器
        4.3.6  数学协处理器及其寄存器
      4.4  四种主要的汇编编程模型
        4.4.1  实模式平面模型
        4.4.2  实模式分段模型
        4.4.33  2位保护模式平面模型
        4.4.46  4位长模式编程模型
    第5章  汇编的正确方式——汇编语言程序的开发过程
      5.1  编程的96种方法
      5.2  文件及其内容
        5.2.1  二进制文件与文本文件
        5.2.2  使用GHex十六进制编辑器查看二进制文件内部
        5.2.3  解释原始数据
        5.2.4  字节顺序
      5.3  输入文本,输出代码
        5.3.1  汇编语言
        5.3.2  注释
        5.3.3  当心“只写源代码”!
        5.3.4  目标代码、链接器和库
        5.3.5  可重定位性
      5.4  汇编语言的开发过程
        5.4.1  工作目录的规则
        5.4.2  编辑源代码文件
        5.4.3  汇编源代码文件
        5.4.4  汇编器错误

        5.4.5  回到编辑器
        5.4.6  编译器警告
      5.5  链接目标代码文件
        5.5.1  链接器错误
        5.5.2  测试EXE文件
        5.5.3  错误与缺陷
        5.5.4  调试器和调试
      5.6  走进汇编语言的世界
        5.6.1  安装软件
        5.6.2  步骤1:在编辑器中编辑程序
        5.6.3  步骤2:使用NASM汇编程序
        5.6.4  步骤3:使用ld链接程序
        5.6.5  步骤4:测试可执行文件
        5.6.6  步骤5:在调试器中观察它的运行
    第6章  一个可使用工具的立足之地——Linux和塑造你的工作方式的工具
      6.1  集成开发环境(IDE)
      6.2  SASM简介
        6.2.1  配置SASM
        6.2.2  SASM的字体
        6.2.3  使用编译器链接
        6.2.4  SASM速览
        6.2.5  SASM的编辑器
        6.2.6  SASM对你的代码有何要求
      6.3  Linux和终端
        6.3.1  Linux控制台
        6.3.2  Konsole中的字符编码
        6.3.3  三个标准UNIX文件
        6.3.4  I/O重定向
        6.3.5  简单文本过滤器
        6.3.6  使用SASM内部的标准输入和标准输出
        6.3.7  使用转义序列进行终端控制
        6.3.8  为什么不使用GUI应用程序
      6.4  使用LinuxMake
        6.4.1  依赖
        6.4.2  当文件是最新的
        6.4.3  依赖链
        6.4.4  调用Make
        6.4.5  为Make创建自定义按键绑定
        6.4.6  使用touch强制构建
      6.5  使用SASM进行调试
    第7章  遵循你的指令——近距离观察机器指令
      7.1  构建自己的沙箱
      7.2  指令及其操作数
      7.3  源操作数和目标操作数
        7.3.1  即时数据
        7.3.2  寄存器数据
        7.3.3  内存数据和有效地址
        7.3.4  混淆数据及其地址
        7.3.5  内存数据的大小
        7.3.6  糟糕的旧时光

      7.4  团结在“标志”周围
        7.4.1  标志礼仪
        7.4.2  在SASM中观察标志
        7.4.3  使用INC和DEC进行加1和减1操作
        7.4.4  标志如何改变程序的执行
        7.4.5  如何检查SASM中的变量
      7.5  有符号值和无符号值
        7.5.1  二进制补码和NEG
        7.5.2  符号扩展和MOVSX
      7.6  隐式操作数和MUL
        7.6.1  MUL和进位标志
        7.6.2  使用DIV进行无符号除法
        7.6.3  MUL和DIV速度很慢
      7.7  阅读和使用汇编语言参考
        7.7.1  复杂记忆的备忘录
        7.7.2  初学者的汇编语言参考
        7.7.3  标志
      7.8  NEG取反(二进制补码,即乘以-1)
        7.8.1  受影响的标志
        7.8.2  有效形式
        7.8.3  示例
        7.8.4  备注
        7.8.5  有效形式
        7.8.6  操作数符号
        7.8.7  示例
        7.8.8  备注
        7.8.9  这里没有提到的内容……
    第8章  我们崇高的目标——创建有效的程序
      8.1  汇编语言程序的骨架
        8.1.1  初始注释块
        8.1.2  .data部分
        8.1.3  .bss部分
        8.1.4  .text部分
        8.1.5  标签
        8.1.6  初始化数据的变量
        8.1.7  字符串变量
        8.1.8  使用EQU和$推导字符串长度
      8.2  通过栈后进先出
        8.2.1  每小时500个盘子
        8.2.2  倒置堆叠
        8.2.3  压入指令
        8.2.4  POP指令登场
        8.2.5  PUSHA和POPA已停用
        8.2.6  压入和弹出的详细信息
        8.2.7  短期存储
      8.3  通过SYSCALL使用Linux内核服务
        8.3.1  通过SYSCALL指令使用x64内核服务
        8.3.2  ABI与API的区别
        8.3.3  ABI的寄存器参数方案
        8.3.4  通过SYSCALL退出程序

        8.3.5  被SYSCALL破坏的寄存器
      8.4  设计一个不平凡的程序
        8.4.1  定义问题
        8.4.2  从伪代码开始
        8.4.3  持续改进
        8.4.4  那些不可避免的惊讶时刻
        8.4.5  扫描缓冲区
        8.4.6  差一错误
        8.4.7  从伪代码到汇编代码
        8.4.8  SASM输出窗口的陷阱
        8.4.9  进一步学习
    第9章  位、标志、分支和表——逐步驶入汇编编程的主航道
      9.1  位就是位(字节也是位)
        9.1.1  位编号
        9.1.2  最合乎逻辑的做法
        9.1.3  AND指令
        9.1.4  掩码位
        9.1.5  OR指令
        9.1.6  XOR(异或)指令
        9.1.7  NOT指令
        9.1.8  分段寄存器没有逻辑
      9.2  移位
        9.2.1  通过什么移位
        9.2.2  移位的工作原理
        9.2.3  将位放入进位标志
        9.2.4  旋转指令
        9.2.5  通过进位标志旋转位
        9.2.6  将已知值设置到进位标志中
      9.3  位操作实战
        9.3.1  将一字节拆分成两个“半字节”
        9.3.2  将高半字节移入低半字节
        9.3.3  使用查找表
        9.3.4  通过移位和加法进行乘法
      9.4  标志、测试和分支
        9.4.1  无条件跳转
        9.4.2  有条件跳转
        9.4.3  在缺少条件的情况下跳转
        9.4.4  标志
        9.4.5  使用CMP进行比较
        9.4.6  跳转指令的“丛林”
        9.4.7  “大于”与“高于”
        9.4.8  使用TEST查找1位
        9.4.9  使用BT寻找0位
      9.5  x64长模式内存寻址详解
        9.5.1  有效地址计算
        9.5.2  位移
        9.5.3  x64位移大小问题
        9.5.4  基址寻址
        9.5.5  基址+位移寻址
        9.5.6  基址+索引寻址

        9.5.7  索引×比例+位移寻址
        9.5.8  其他寻址方案
        9.5.9  LEA:绝密数学机器
      9.6  字符表转换
        9.6.1  转换表
        9.6.2  使用MOV或XLAT进行转换
      9.7  用表代替计算
    第10章  分而治之——使用过程和宏来应对程序复杂性
      10.1  层层嵌套
      10.2  调用和返回
        10.2.1  调用中的调用
        10.2.2  意外递归的危险
        10.2.3  需要警惕的标志相关错误
        10.2.4  过程及其所需的数据
        10.2.5  保存调用者的寄存器
        10.2.6  在Linux系统调用中保存寄存器
        10.2.7  PUSHAD和POPAD已废弃
        10.2.8  本地数据
        10.2.9  在过程定义中放置常量数据
        10.2.10  更多表技巧
      10.3  本地标签和跳转的长度
        10.3.1  强制本地标签访问
        10.3.2  短、近和远跳转
      10.4  构建外部过程库
        10.4.1  当工具达到极限时
        10.4.2  在SASM中使用包含文件
        10.4.3  SASM包含文件的存储位置
        10.4.4  创建包含文件库的最佳方法
        10.4.5  独立汇编和模块
        10.4.6  全局和外部声明
        10.4.7  全局变量和外部变量的机制
        10.4.8  将库链接到程序中
        10.4.9  太多过程和库会造成危险
      10.5  制作过程的艺术
        10.5.1  可维护性和重用性
        10.5.2  决定什么应该是一个过程
        10.5.3  使用注释标题
      10.6  Linux控制台中的简单光标控制
      10.7  创建和使用宏
        10.7.1  宏定义的机制
        10.7.2  定义带参数的宏
        10.7.3  调用宏的机制
        10.7.4  宏内的本地标签
        10.7.5  宏库作为包含文件
        10.7.6  宏与过程:优点和缺点
    第11章  字符串及其他——那些令人惊叹的字符串指令
      11.1  汇编语言字符串的概念
        11.1.1  彻底改变你的“字符串感”
        11.1.2  源字符串和目标字符串
        11.1.3  文本显示虚拟屏幕

      11.2  REPSTOSB:软件机关枪
        11.2.1  机关枪式操作虚拟显示
        11.2.2  执行STOSB指令
        11.2.3  STOSB和方向标志DF
        11.2.4  定义显示缓冲区中的行
        11.2.5  将缓冲区发送到Linux控制台
      11.3  半自动武器:没有REP的STOSB
        11.3.1  谁减少了RCX?
        11.3.2  LOOP指令
        11.3.3  在屏幕上显示标尺
        11.3.4  MUL不是IMUL
        11.3.5  Ruler的教训
        11.3.6  STOS的四种大小
        11.3.7  再见,BCD算术
      11.4  MOVSB:快速块复制
        11.4.1  DF和重叠阻挡移动
        11.4.2  单步REP字符串指令
      11.5  将数据存储到不连续的字符串中
        11.5.1  显示一个ASCII表
        11.5.2  嵌套指令循环
        11.5.3  当RCX变为0时跳转
        11.5.4  关闭内循环
        11.5.5  关闭外循环
        11.5.6  回顾showchar
      11.6  命令行参数、字符串搜索和Linux栈
        11.6.1  显示SASM的命令行参数
        11.6.2  使用SCASB进行字符串搜索
        11.6.3  REPNE与REPE
        11.6.4  无法将命令行参数传递给SASM中的程序
      11.7  栈及其结构和使用方法
        11.7.1  直接访问栈
        11.7.2  程序序言和结语
        11.7.3  栈上的寻址数据
        11.7.4  不要弹出
    第12章  转向C——调用C语言编写的外部函数
      12.1  GNU
        12.1.1  瑞士军刀编译器
        12.1.2  以GNU方式构建代码
        12.1.3  SASM使用GCC
        12.1.4  如何在汇编工作中使用gcc
        12.1.5  为什么不使用gas
      12.2  链接标准C库
        12.2.1  C调用约定
        12.2.2  调用者、被调用者和破坏者
        12.2.3  设置栈帧
        12.2.4  在结语中销毁栈帧
        12.2.5  栈对齐
        12.2.6  通过puts()输出字符
      12.3  使用printf()格式化文本输出
        12.3.1  将参数传递给printf()

        12.3.2  printf()需要在RAX中加上前置
        12.3.3  你需要使用-no-pie选项
      12.4  使用fgets()和scanf()输入数据
      12.5  成为Linux时间领主
        12.5.1  C库的时间机器
        12.5.2  从系统时钟获取time_t值
        12.5.3  将time_t值转换为格式化字符串
        12.5.4  生成单独的本地时间值
        12.5.5  使用MOVSD复制glibc的tm结构
      12.6  理解AT&T指令助记符
        12.6.1  AT&T助记符约定
        12.6.2  AT&T内存引用语法
      12.7  生成随机数
        12.7.1  使用srand()为生成器设定种子
        12.7.2  生成伪随机数
        12.7.3  相比之下有些比特更随机
        12.7.4  调用寄存器中的地址
        12.7.5  使用puts()将一个裸换行符发送到控制台
        12.7.6  如何向libc函数传递六个以上的参数
      12.8  C语言如何处理命令行参数
      12.9  简单文件I/O
        12.9.1  使用sscanf()将字符串转换为数字
        12.9.2  创建和打开文件
        12.9.3  使用fgets()从文件读取文本
        12.9.4  使用fprintf()将文本写入文件
        12.9.5  将过程收集到库中的注意事项
      12.10  永远学习,永远不要停下来
        12.10.1  何去何从
        12.10.2  走出原点
    (以下内容可扫描封底二维码下载)
    附录A  Insight调试器的回归
    附录B  部分x64指令参考
    附录C  字符集图表