具体描述
编辑推荐
本书全面、系统、深入地介绍x86处理器在实模式,特别是保护模式下的工作原理 ,解开了计算机从16位到32位工作模式的秘密;还以大量的实例,多侧面地展示了操作系统在整个计算机系统中的地位和作用。 内容简介
李忠编著的《x86汇编语言:从实模式到保护模式》采用开源的NASM汇编语言编译器和VirtualBox虚拟机软件,以个人计算机广泛采用的Intel处理器为基础,详细讲解了Intel处理器的指令系统和工作模式,以大量的代码演示了16/32/64位软件的开发方法,介绍了处理器的16位实模式和32位保护模式,以及基本的指令系统。
《x86汇编语言:从实模式到保护模式》是一本有趣的书,它没有把篇幅花在计算一些枯燥的数学题上。相反,它教你如何直接控制硬件,在不借助于BIOS、DOS、Windows、Linux或者任何其他软件支持的情况下来显示字符、读取硬盘数据、控制其他硬件等。本书可作为大专院校相关专业学生和计算机编程爱好者的教程。 目录
第1部分 预备知识
第1章 十六进制计数法
1.1 二进制计数法回顾
1.1.1 关于二进制计数法
1.1.2 二进制到十进制的转换
1.1.3 十进制到二进制的转换
1.2 十六进制计数法
1.2.1 十六进制计数法的原理
1.2.2 十六进制到十进制的转换
1.2.3 十进制到十六进制的转换
1.3 为什么需要十六进制
本章习题
第2章 处理器、内存和指令
2.1 最早的处理器
2.2 寄存器和算术逻辑部件
2.3 内存储器
2.4 指令和指令集
2.5 古老的Intel 处理器
2.5.1 的通用寄存器
2.5.2 程序的重定位难题
2.5.3 内存分段机制
2.5.4 的内存分段机制
本章习题
第3章 汇编语言和汇编软件
3.1 汇编语言简介
3.2 NASM编译器
3.2.1 从网上下载NASM安装程序
3.2.2 安装NASM编译器
3.2.3 下载配书源码和工具
3.2.4 用Nasmide体验代码的书写和编译过程
3.2.5 用HexView观察编译后的机器代码
本章习题
第4章 虚拟机的安装和使用
4.1 计算机的启动过程
4.1.1 如何将编译好的程序提交给处理器
4.1.2 计算机的加电和复位
4.1.3 基本输入输出系统
4.1.4 硬盘及其工作原理
4.1.5 一切从主引导扇区开始
4.2 创建和使用虚拟机
4.2.1 别害怕,虚拟机是软件
4.2.2 下载Oracle VM VirtualBox
4.2.3 安装Oracle VM VirtualBox
4.2.4 创建一台虚拟PC
4.2.5 虚拟硬盘简介
4.2.6 练习使用FixVhdWr工具向虚拟硬盘写数据
第2部分 位处理器下的实模式
第5章 编写主引导扇区代码
5.1 欢迎来到主引导扇区
5.2 注释
5.3 在屏幕上显示文字
5.3.1 显卡和显存
5.3.2 初始化段寄存器
5.3.3 显存的访问和ASCII代码
5.3.4 显示字符
5.4 显示标号的汇编地址
5.4.1 标号
5.4.2 如何显示十进制数字
5.4.3 在程序中声明并初始化数据
5.4.4 分解数的各个数位
5.4.5 显示分解出来的各个数位
5.5 使程序进入无限循环状态
5.6 完成并编译主引导扇区代码
5.6.1 主引导扇区有效标志
5.6.2 代码的保存和编译
5.7 加载和运行主引导扇区代码
5.7.1 把编译后的指令写入主引导扇区
5.7.2 启动虚拟机观察运行结果
5.7.3 程序的调试
本章习题
第6章 相同的功能,不同的代码
6.1 代码清单6-1
6.2 跳过非指令的数据区
6.3 在数据声明中使用字面值
6.4 段地址的初始化
6.5 段之间的批量数据传送
6.6 使用循环分解数位
6.7 计算机中的负数
6.7.1 无符号数和有符号数
6.7.2 处理器视角中的数据类型
6.8 数位的显示
6.9 其他标志位和条件转移指令
6.9.1 奇偶标志位PF
6.9.2 进位标志CF
6.9.3 溢出标志OF
6.9.4 现有指令对标志位的影响
6.9.5 条件转移指令
6.10 NASM编译器的$和$$标记
6.11 观察运行结果
本章习题
第7章 比高斯更快的计算
7.1 从1加到100的故事
7.2 代码清单7-1
7.3 显示字符串
7.4 计算1到100的累加和
7.5 累加和各个数位的分解与显示
7.5.1 堆栈和堆栈段的初始化
7.5.2 分解各个数位并压栈
7.5.3 出栈并显示各个数位
7.5.4 进一步认识堆栈
7.6 程序的编译和运行
7.7 处理器的寻址方式
7.7.1 寄存器寻址
7.7.2 立即寻址
7.7.3 内存寻址
本章习题
第8章 硬盘和显卡的访问与控制
8.1 本章代码清单
8.1.1 本章意图
8.1.2 代码清单8-1
8.2 用户程序的结构
8.2.1 分段、段的汇编地址和段内汇编地址
8.2.2 用户程序头部
8.3 加载程序(器)的工作流程
8.3.1 初始化和决定加载位置
8.3.2 准备加载用户程序
8.3.3 外围设备及其接口
8.3.4 I/O端口和端口访问
8.3.5 通过硬盘控制器端口读扇区数据
8.3.6 过程调用
8.3.7 加载用户程序
8.3.8 用户程序重定位
8.3.9 将控制权交给用户程序
8.3.10 处理器的无条件转移指令
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 滚动屏幕内容
8.4.9 重置光标
8.4.10 切换到另一个代码段中执行
8.4.11 访问另一个数据段
8.5 编译和运行程序并观察结果
本章习题
第9章 中断和动态时钟显示
9.1 外部硬件中断
9.1.1 非屏蔽中断
9.1.2 可屏蔽中断
9.1.3 实模式下的中断向量表
9.1.4 实时时钟、CMOS RAM和BCD编码
9.1.5 代码清单9-1
9.1.6 初始化8259、RTC和中断向量表
9.1.7 使处理器进入低功耗状态
9.1.8 实时时钟中断的处理过程
9.1.9 代码清单9-1的编译和运行
9.2 内部中断
9.3 软中断
9.3.1 常用的BIOS中断
9.3.2 代码清单9-2
9.3.3 从键盘读字符并显示
9.3.4 代码清单9-2的编译和运行
本章习题
第3部分 位保护模式
第10章 位Intel微处理器编程架构
10.1 IA-32架构的基本执行环境
10.1.1 寄存器的扩展
10.1.2 基本的工作模式
10.1.3 线性地址
10.2 现代处理器的结构和特点
10.2.1 流水线
10.2.2 高速缓存
10.2.3 乱序执行
10.2.4 寄存器重命名
10.2.5 分支目标预测
10.3 位模式的指令系统
10.3.1 位处理器的寻址方式
10.3.2 操作数大小的指令前缀
10.3.3 一般指令的扩展
本章习题
第11章 进入保护模式
11.1 代码清单11-1
11.2 全局描述符表
11.3 存储器的段描述符
11.4 安装存储器的段描述符并加载GDTR
11.5 关于第21条地址线A20的问题
11.6 保护模式下的内存访问
11.7 清空流水线并串行化处理器
11.8 保护模式下的堆栈
11.8.1 关于堆栈段描述符中的界限值
11.8.2 检验32位下的堆栈操作
11.9 程序的编译和运行
本章习题
第12章 存储器的保护
12.1 代码清单12-1
12.2 进入32位保护模式
12.2.1 话说mov ds,ax和mov ds,eax
12.2.2 创建GDT并安装段描述符
12.3 修改段寄存器时的保护
12.4 地址变换时的保护
12.4.1 代码段执行时的保护
12.4.2 堆栈操作时的保护
12.4.3 数据访问时的保护
12.5 使用别名访问代码段对字符排序
12.6 程序的编译和运行
本章习题
第13章 程序的动态加载和执行
13.1 本章代码清单
13.2 内核的结构、功能和加载
13.2.1 内核的结构
13.2.2 内核的加载
13.2.3 安装内核的段描述符
13.3 在内核中执行
13.4 用户程序的加载和重定位
13.4.1 用户程序的结构
13.4.2 计算用户程序占用的扇区数
13.4.3 简单的动态内存分配
13.4.4 段的重定位和描述符的创建
13.4.5 重定位用户程序内的符号地址
13.5 执行用户程序
13.6 代码的编译、运行和调试
本章习题
第14章 任务和特权级保护
14.1 任务的隔离和特权级保护
14.1.1 任务、任务的LDT和TSS
14.1.2 全局空间和局部空间
14.1.3 特权级保护概述
14.2 代码清单14-1
14.3 内核程序的初始化
14.3.1 调用门
14.3.2 调用门的安装和测试
14.4 加载用户程序并创建任务
14.4.1 任务控制块和TCB链
14.4.2 使用堆栈传递过程参数
14.4.3 加载用户程序
14.4.4 创建局部描述符表
14.4.5 重定位U-SALT表
14.4.6 创建0、1和2特权级的堆栈
14.4.7 安装LDT描述符到GDT中
14.4.8 任务状态段TSS的格式
14.4.9 创建任务状态段TSS
14.4.10 安装TSS描述符到GDT中
14.4.11 带参数的过程返回指令
14.5 用户程序的执行
14.5.1 通过调用门转移控制的完整过程
14.5.2 进入3特权级的用户程序的执行
14.5.3 检查调用者的请求特权级RPL
本章习题
第15章 任 务 切 换
15.1 本章代码清单
15.2 任务切换前的设置
15.3 任务切换的方法
15.4 用call/jmp/iret指令发起任务切换的实例
15.5 处理器在实施任务切换时的操作
15.6 程序的编译和运行
本章习题
第16章 分页机制和动态页面分配
16.1 分页机制概述
16.1.1 简单的分页模型
16.1.2 页目录、页表和页
16.1.3 地址变换的具体过程
16.2 本章代码清单
16.3 使内核在分页机制下工作
16.3.1 创建内核的页目录和页表
16.3.2 任务全局空间和局部空间的页面映射
16.4 创建内核任务
16.4.1 内核的虚拟内存分配
16.4.2 页面位映射串和空闲页的查找
16.4.3 创建页表并登记分配的页
16.4.4 创建内核任务的TSS
16.5 用户任务的创建和切换
16.5.1 多段模型和段页式内存管理
16.5.2 平坦模型和用户程序的结构
16.5.3 用户任务的虚拟地址空间分配
16.5.4 用户程序的加载
16.5.5 段描述符的创建(平坦模型)
16.5.6 重定位U-SALT并复制页目录表
16.5.7 切换到用户任务执行
16.6 程序的编译和执行
本章习题
第17章 中断和异常的处理
17.1 中断和异常
17.1.1 中断和异常概述
17.1.2 中断描述符表、中断门和陷阱门
17.1.3 中断和异常处理程序的保护
17.1.4 中断任务
17.1.5 错误代码
17.2 本章代码清单
17.3 内核的加载和初始化
17.3.1 彻底终结多段模型
17.3.2 创建中断描述符表
17.3.3 用定时中断实施任务切换
17.3.4 A芯片的初始化
17.3.5 平坦模型下的字符串显示例程
17.4 内核任务的创建
17.4.1 创建内核任务的TCB
17.4.2 宏汇编技术
17.5 用户任务的创建
17.5.1 准备加载用户程序
17.5.2 转换后援缓冲器的刷新
17.5.3 用户任务的创建和初始化
17.6 程序的编译和执行
本章习题 前言/序言
x86汇编语言:从实模式到保护模式 一、 拨开迷雾,直击底层:为何我们需要深入理解x86汇编? 在当今软件开发领域,高级语言如C++、Java、Python等已成为主流,它们提供了更高的抽象层次,极大地提高了开发效率。然而,在追求效率的同时,我们是否已经渐渐遗忘了硬件的真实运作方式?软件的性能瓶颈、操作系统的核心机制、嵌入式系统的资源限制、乃至安全漏洞的根源,都深深地根植于底层硬件的指令集。x86架构作为当今绝大多数桌面、笔记本及服务器计算机的核心,其汇编语言便是理解这一切的钥匙。 本书《x86汇编语言:从实模式到保护模式》并非仅仅是一本枯燥的指令手册,它更是一次穿越时空的探索之旅,一次对计算机底层奥秘的深度挖掘。我们将从最基础的处理器运作模型出发,逐步揭开x86架构的神秘面纱。理解汇编语言,不仅仅是为了能够编写出更高效的代码,更是为了: 洞察程序执行的每一个细节: 当高级语言的代码被编译后,最终会转化为一系列x86指令。掌握汇编,意味着你能够“看到”程序在CPU内部是如何一步步被执行的,理解函数调用、变量存储、内存访问的真实机制。 攻克性能瓶颈的利器: 在性能至关重要的场景,如游戏引擎、高性能计算、实时操作系统等,汇编语言能够让你对CPU资源进行最精细、最直接的控制,优化代码的每一条指令,从而榨干硬件的每一分潜力。 理解操作系统的基石: 操作系统的核心,如引导加载程序、进程调度、内存管理、中断处理等,无一不依赖于汇编语言来完成。理解这些底层机制,对于深入理解操作系统的工作原理至关重要。 驾驭嵌入式系统的挑战: 嵌入式系统通常资源受限,需要极致的效率和对硬件的精确控制。x86汇编语言是开发和调试这类系统的必备技能。 深入安全研究的殿堂: 许多安全漏洞,如缓冲区溢出、返回导向编程(ROP)等,都直接与内存布局和指令执行相关。掌握汇编语言是理解和防御这些攻击的关键。 重新审视编程思维: 学习汇编语言的过程,能够强迫我们以一种全新的、更贴近机器的方式思考问题,培养严谨的逻辑思维和细致的编程习惯。 本书将引导读者从最原始、最纯粹的实模式开始,逐步过渡到功能更强大、更复杂的保护模式。这不仅仅是两种模式的切换,更是对x86架构发展历程和技术演进的一次生动呈现。通过本书的学习,你将不再是被高级语言“蒙蔽”的开发者,而是能够理解并驾驭计算机底层力量的真正“匠人”。 二、 实模式:回溯历史,理解最本源的CPU运作 在现代操作系统繁荣昌盛的今天,我们可能很难想象早期计算机的运作方式。实模式,便是x86处理器最初的设计形态,它承载了Intel 8086/8088 CPU的辉煌岁月,也是IBM PC早期运行的基础。本书将带领读者深入实模式的细节,理解它为何存在,又为何被淘汰。 在实模式下,CPU直接访问物理内存,地址空间被限制在1MB。这看似简单,却蕴含着许多重要的概念: 段式内存管理: 实模式最显著的特征便是其段式内存管理。我们将详细讲解段寄存器(CS, DS, SS, ES)的运作方式,如何通过段基地址与偏移地址的组合来访问内存。理解段与段之间的关系,以及它们如何共同构成1MB的地址空间,是掌握实模式的关键。 基础指令集与寻址模式: 我们将详细介绍x86汇编语言中最基本、最核心的指令,包括数据传送指令(MOV)、算术运算指令(ADD, SUB, MUL, DIV)、逻辑运算指令(AND, OR, XOR, NOT)、位移指令(SHL, SHR, SAL, SAR)等。同时,深入剖析各种寻址模式,如立即数寻址、寄存器寻址、直接寻址、基址寻址、变址寻址、基址变址寻址等,理解CPU如何根据指令的上下文找到要操作的数据。 寄存器:CPU的“工作台”: CPU内部的通用寄存器(AX, BX, CX, DX, SI, DI, BP, SP)、段寄存器、指令指针(IP)和标志寄存器(FLAGS)扮演着至关重要的角色。本书将一一解析这些寄存器的功能和用途,理解它们在指令执行过程中的作用。 中断与中断向量表: 中断是CPU处理外部事件(如键盘输入、定时器)或内部异常(如除零)的重要机制。我们将详细讲解实模式下的中断处理流程,中断向量表的概念,以及如何编写中断服务例程。 BIOS与DOS:实模式下的操作系统环境: 了解实模式下的BIOS(基本输入输出系统)如何初始化硬件,以及早期的DOS操作系统是如何在实模式下运行的。我们将通过实际的汇编代码示例,让读者体验编写能够直接与硬件交互的程序。 学习实模式,如同考古学家挖掘古老的遗迹。它能够帮助我们建立起对计算机最本源的理解,为后续更复杂的概念打下坚实的基础。通过掌握实模式下的编程,你将能够编写出直接操作硬件的简单程序,体验计算机最原始的运作魅力。 三、 保护模式:解锁强大的内存管理与多任务能力 随着计算机性能的飞跃和应用复杂度的提升,实模式的局限性日益凸显。1MB的内存限制、缺乏内存保护机制、不支持多任务等问题,使得CPU的发展必须迈向一个新的阶段——保护模式。本书将系统地讲解保护模式下的x86架构,这是现代计算机运行的基础。 保护模式的核心在于其强大的内存管理和对操作系统的支持能力,它引入了许多关键性的概念: 分段与分页: 这是保护模式下内存管理的两大支柱。 段式内存管理(增强版): 虽然保护模式仍然使用段,但与实模式不同的是,保护模式下的段提供了更强大的保护机制。我们将深入理解段描述符、全局描述符表(GDT)和局部描述符表(LDT)的作用,以及它们如何实现内存访问权限的控制,防止程序越界访问。 分页机制: 为了突破1MB的内存限制,并进一步增强内存保护和多任务支持,分页机制应运而生。我们将详细讲解页目录、页表、页帧等概念,理解CPU如何将线性地址转换为物理地址,实现虚拟内存和内存共享。 特权级别: 保护模式引入了四个特权级别(Ring 0 到 Ring 3),用于区分操作系统内核和用户应用程序的权限。我们将分析不同特权级别下的访问控制规则,以及它们如何实现操作系统的安全性和稳定性。 中断与异常处理(保护模式): 保护模式下的中断和异常处理机制比实模式更加复杂和强大,引入了中断描述符表(IDT)等新结构,并支持更精细的异常捕获和处理。 任务切换与多任务: 保护模式为实现真正的多任务操作系统提供了硬件支持。我们将讲解任务控制块(TSS)的概念,以及CPU如何通过硬件机制进行任务切换,为现代操作系统的多任务运行奠定基础。 全局描述符表(GDT)与中断描述符表(IDT)的构建与使用: 这两个表格是保护模式下内存管理和中断处理的核心。本书将通过详细的示例,指导读者如何正确地构建和使用GDT和IDT,理解它们在CPU运行过程中的关键作用。 从实模式到保护模式的转变,是x86架构的一次重大飞跃。本书将带领读者一步步理解这些复杂而强大的机制,让你能够编写出在保护模式下运行的程序,理解现代操作系统是如何管理内存、保护程序、实现多任务的。 四、 实践出真知:理论与实践的深度结合 本书并非仅仅停留在理论的讲解,我们深知汇编语言的精髓在于实践。因此,每一章节的讲解都将伴随着精心设计的汇编代码示例。这些示例将覆盖从最基础的“Hello, World!”程序,到复杂的内存管理、中断处理、甚至简易的操作系统引导过程。 汇编器与调试器的使用: 我们将介绍常用的汇编器(如NASM、MASM)和调试器(如GDB、WinDbg)的使用方法,让你能够独立地编译、链接和调试你的汇编程序。 循序渐进的示例: 示例代码将从简单指令的运用开始,逐步引入段、页、中断等复杂概念,确保读者能够逐步消化和理解。 常见问题的解答与技巧分享: 在学习过程中,我们预见到读者可能会遇到的常见问题,并提供相应的解答和实用的编程技巧,帮助你少走弯路。 引导读者动手实践: 本书鼓励读者动手修改示例代码,尝试不同的指令和寻址方式,通过实际操作来加深理解。 五、 谁适合阅读本书? 《x86汇编语言:从实模式到保护模式》适合以下读者: 计算机科学专业的学生: 深入理解计算机组成原理、操作系统、编译原理等课程的必备参考。 对底层技术充满好奇的开发者: 希望了解程序在硬件上是如何运行的,从而提升代码性能、解决疑难问题的开发者。 嵌入式系统开发者: 需要精细控制硬件、优化资源使用的嵌入式工程师。 安全研究人员: 想要深入理解漏洞原理、进行逆向工程和安全攻防的从业者。 对汇编语言感兴趣的任何技术爱好者: 愿意投入时间和精力,探索计算机世界最本质运行机制的学习者。 六、 结语 掌握x86汇编语言,如同拥有了一把开启计算机底层世界的钥匙。它能够让你从一个“代码使用者”蜕变为一个“底层掌控者”。《x86汇编语言:从实模式到保护模式》将是你踏上这条探索之路的可靠向导。我们相信,通过本书的学习,你将能够拨开迷雾,直击底层,深刻理解计算机的运作之道,并在你的技术生涯中受益匪浅。