本系列文章是本人关于汇编语言:基于x86处理器期末复习笔记;仅供学习参考;(本人cqupt软工生,欢迎学弟学妹阅读学习)
1.1 欢迎来到汇编语言的世界
- 工具介绍:
- 汇编器: 将汇编语言源程序转换为机器语言。
- 链接器: 将汇编器生成的文件组合成可执行程序。
- 调试器: 运行时单步执行程序,检查寄存器和内存状态。
- MASM 程序类型:
- 32位保护模式: 适用于所有 32 位和 64 位 Windows 系统。
- 64位模式: 适用于所有 64 位 Windows 系统。
- 16位实地址模式: 适用于 32 位 Windows 和嵌入式系统 (64 位 Windows 不支持)。
1.1.1 读者可能会问的问题
- 背景知识: 结构化高级语言编程经验。
- 汇编器和链接器: 将源程序转换为机器语言和可执行程序。
- MASM 程序类型: 32位保护模式、64位模式和 16位实地址模式。
- 汇编语言与机器语言: 一对一关系,每条汇编指令对应一条机器指令。
- 汇编语言与 C++/Java: 一对多关系,高级语言语句会扩展为多条汇编指令。
- 汇编语言可移植性: 针对特定处理器系列,不可移植。
- 学习汇编语言的原因:
- 嵌入式系统编程,内存占用少
- 实时应用程序,精确定时和响应
- 电脑游戏优化,减少代码大小和加快执行速度
- 计算机软硬件理解,位控制
- 设备驱动程序开发
- 汇编语言规则: 基于处理器和机器语言的物理局限性,规则较少,但调试复杂。
1.1.2 汇编语言的应用
- 高级语言: 适用于大型应用程序,可移植性好。
- 汇编语言: 适用于嵌入式系统、电脑游戏、硬件驱动程序等需要直接访问硬件的应用程序。
- C/C++: 平衡高级结构和底层细节,可移植性较差。
1.1.3 本节回顾
- 汇编器和链接器是如何一起工作的?
○ 汇编器:将汇编语言源程序转换为机器语言目标代码。
○ 链接器:将多个目标代码文件组合成一个可执行程序,并解决程序中不同模块之间的符号引用。
○ 调试器:在程序运行时,单步执行程序并检查寄存器和内存状态,帮助程序员查找和修复错误。 - 学习汇编语言如何能提高你对操作系统的理解?
○ 汇编语言允许你直接访问计算机硬件和操作系统提供的底层服务,例如中断处理程序和系统调用。
○ 通过学习汇编语言,你可以更好地理解操作系统如何管理内存、处理进程和线程,以及执行系统调用。 - 比较高级语言和机器语言时,一对多关系是什么意思?
○ 在高级语言中,一条语句可以转换为多条机器语言指令,这称为一对多关系。
○ 例如,C++中的一条赋值语句可能会被转换为几条汇编指令,这些汇编指令再被转换为机器语言指令。 - 解释编程语言中的可移植性概念。
○ 可移植性是指程序能够在不同的计算机系统上运行,而无需进行重大修改。
○ 高级语言通常具有良好的可移植性,因为它们使用标准化的语法和语义,而汇编语言的可移植性较差,因为它依赖于特定的处理器架构。 - x86处理器的汇编语言与Vax或Motorola 68x00等机器的汇编语言是一样的吗?
○ 不一样。不同的处理器架构具有不同的指令集,因此它们的汇编语言也不同。 - 举一个嵌入式系统应用程序的例子。
○ 汽车发动机控制系统:监控发动机状态并调整燃油喷射量和点火时间。 - 什么是设备驱动程序?
○ 设备驱动程序是一种程序,它将通用操作系统指令转换为对硬件细节的具体引用,例如打印机的驱动程序。 - 汇编语言和C/C++语言中的指针变量类型检查,哪一个更强(更严格)?
○ 汇编语言没有指针变量类型检查,而C/C++语言具有严格的指针变量类型检查。 - 给出两种应用类型,与高级语言相比,它们更适合使用汇编语言。
○ 实时系统:需要精确定时和快速响应的系统,例如飞机控制系统。
○ 性能关键的应用程序:需要最大性能的系统,例如游戏引擎。 - 编写程序来直接访问打印机端口时,为什么高级语言不是理想工具?
○ 高级语言通常不提供对硬件端口的直接访问,而汇编语言可以访问所有内存地址和硬件端口。 - 为什么汇编语言不常用于编写大型应用程序?
○ 汇编语言编写和维护困难,代码难以阅读和理解,且可移植性差。 - 挑战:参考本章前面给出的例子,将下述C++表达式转换为汇编语言:X=(Y*4)+3。
mov eax, Y ; 将 Y 的值移动到 EAX 寄存器
shl eax, 2 ; 将 EAX 寄存器的值左移 2 位,相当于乘以 4
add eax, 3 ; 将 EAX 寄存器的值加 3
mov X, eax ; 将 EAX 寄存器的值移动到 X
- 虚拟机: 模拟其他计算机功能的软件程序,用于简化程序开发。
- 虚拟机层次: 【记忆】
- Level 1: 汇编语言
- Level 2: 指令集架构 (ISA)
- Level 3: 数字逻辑硬件
- JVM: Java 虚拟机,使 Java 程序能够在各种计算机上运行。
1.3 数据表示
- 数制系统: 二进制、八进制、十进制、十六进制。
- 二进制整数: 由 0 和 1 组成,可表示有符号和无符号整数。
- 无符号二进制整数: 每位表示 2 的幂,从 LSB 到 MSB。
- 二进制加法: 位对位加法,进位传递到更高位。
- 整数存储大小: 字节、字、双字、四字、八字。
- 十六进制整数: 每个十六进制数字表示 4 位二进制位。
- 有符号二进制整数: 使用补码表示,最高位为符号位。
- 字符存储: 使用字符集将字符映射为整数,如 ASCII、ANSI、Unicode。
- ASCII 字符串: 以空字节结束的字符序列。
1.4 布尔表达式
- 布尔代数: 定义一组操作,其值为真或假。
- 布尔运算符: 非 (NOT)、与 (AND)、或 (OR)。
- 布尔函数: 接收布尔输入,生成布尔输出。
- 真值表: 展示布尔函数所有可能的输入和输出。【之前考到了】
- 运算符优先级: NOT > AND > OR
问题 1: 描述布尔表达式 ¬X∨Y。
答案: ¬X∨Y 表示 X 为假或 Y 为真。当 X 为假时,无论 Y 的值如何,表达式都为真;当 X 为真时,只有 Y 为真时,表达式才为真。
问题 2: 描述布尔表达式 (X∧Y)。
答案: (X∧Y) 表示 X 和 Y 都为真。只有当 X 和 Y 都为真时,表达式才为真;否则,表达式为假。
问题 3: 布尔表达式 (T∧F)∨T 的值是什么?
答案: (T∧F)∨T = F∨T = T。因为 T 与任何值进行或运算都为真。
问题 4: 布尔表达式 ¬(F∨T) 的值是什么?
答案: ¬(F∨T) = ¬T = F。因为 T 的否定为假。
第二章
1. x86处理器架构
- 基本微机设计:
- 中央处理单元 (CPU) 作为核心,负责执行指令和数据处理。
- 寄存器作为高速存储位置,用于存储数据和指令。
- 时钟用于同步CPU内部操作和系统其他组件。
- 控制单元协调指令执行步骤。
- 算术逻辑单元 (ALU) 执行算术和逻辑运算。
- 总线用于数据传输,包括数据总线、I/O总线、控制总线和地址总线。
- 中央处理单元 (CPU) 作为核心,负责执行指令和数据处理。
- 指令执行周期: 指令执行经历取指、译码和执行三个步骤。
- 读取内存: CPU通过地址总线访问内存,将指令和数据传输到寄存器进行处理。
- Cache存储器: 为了提高内存访问速度,CPU内部集成了Cache存储器,用于存储近期使用过的指令和数据。命中与未命中
- 加载并执行程序: 操作系统将程序文件加载到内存,并设置CPU指向程序的入口地址,从而开始执行程序。
- 中央处理单元(CPU)包含寄存器和哪些其他基本部件?
CPU 包含以下基本部件:
- 寄存器: 用于存储数据和指令的高速存储位置。
- 算术逻辑单元(ALU): 执行算术运算(如加法和减法)和逻辑运算(如 AND、OR 和 NOT)。
- 控制单元(CU): 协调指令执行的步骤序列。
- 时钟: 同步 CPU 内部操作和系统其他组件。
- 中央处理单元通过哪三种总线与计算机系统的其他部分相连?
CPU 通过以下三种总线与计算机系统的其他部分相连:
- 数据总线: 在 CPU 和内存之间传输指令和数据。
- I/O 总线: 在 CPU 和系统输入/输出设备之间传输数据。
- 地址总线: 用于保持指令和数据的地址。
- 为什么访问存储器比访问寄存器要花费更多的机器周期?
访问存储器比访问寄存器要花费更多的机器周期,因为:
- 从内存读取一个值需要经过多个步骤,包括设置地址、发送读取信号、等待响应等。
- CPU 和内存之间存在速度差异,需要等待内存准备数据。
- 与 CPU 寄存器相比,内存的访问速度较慢。
- 指令执行周期包含哪三个基本步骤?
指令执行周期包含以下三个基本步骤:
- 取指(Fetch): 从内存读取指令到指令队列,并更新指令指针。
- 译码(Decode): 对指令的二进制位模式进行译码,确定指令的操作和操作数。
- 执行(Execute): 使用操作数执行指令,并更新状态标志位。
- 指令执行周期中,如果用到存储器操作数,则还需要哪两个步骤?
如果用到存储器操作数,指令执行周期还需要以下两个步骤:
- 读取操作数: 从内存读取操作数到寄存器。
- 存放结果: 将指令执行结果写回内存。
2. 32位x86处理器
- 操作模式: x86处理器支持保护模式、实地址模式、系统管理模式、虚拟8086模式。
- 基本执行环境:
- 地址空间: 32位保护模式下,程序最大可以寻址4GB的线性地址空间。
- 基本程序执行寄存器: 包括8个通用寄存器、6个段寄存器、EFLAGS(状态标志)寄存器和EIP(指令指针)寄存器。
- 通用寄存器的特殊用法:【记忆】
- EAX (累加器):
- 默认的乘除法操作数寄存器。
- 程序返回值寄存器。
ECX (计数器): - 默认的循环计数器寄存器。
- 字符串操作指令的计数寄存器。
EDX (数据): - 默认的除法操作数寄存器。
- 输入输出操作中的数据寄存器。
EBX (基址): - 常用于存储基址,例如数组或结构的基地址。
- 在堆栈操作中,有时用于临时存储值。
ESP (堆栈指针): - 指向堆栈顶部,用于堆栈操作。
- 通常不用于一般的算术运算和数据传输。
EBP (基址指针): - 常用于存储函数的基址指针,用于访问函数参数和局部变量。
- 也称为帧指针,用于跟踪堆栈帧。
ESI (源索引): - 字符串操作指令中的源索引寄存器,指向源字符串的当前字符。
- 也称为源变址寄存器。
EDI (目的索引): - 字符串操作指令中的目的索引寄存器,指向目的字符串的当前字符。
- 也称为目的变址寄存器。
- 通用寄存器的特殊用法:【记忆】
- MMX寄存器: 用于SIMD指令,对数据进行并行操作。
- XMM寄存器: 用于SIMD流扩展指令集。
- 浮点单元: 执行浮点算术运算。
- x86内存管理: x86处理器根据操作模式管理内存,包括实地址模式和保护模式。
- x86 处理器的 3 个基本操作模式是什么?
- 保护模式 (Protected Mode): 处理器的原生状态,支持所有指令和特性,并提供内存保护机制。
- 实地址模式 (Real-Address Mode): 模拟早期 Intel 处理器的编程环境,可以直接访问系统内存和硬件设备。
- 系统管理模式 (System Management Mode): 向操作系统提供实现电源管理和系统安全等功能的机制。
- 给出 8 个 32 位通用寄存器的名称。
- EAX
- EBX
- ECX
- EDX
- ESI
- EDI
- EBP
- ESP
- 给出 6 个段寄存器的名称。
- CS (代码段)
- SS (堆栈段)
- DS (数据段)
- ES (附加数据段)
- FS
- GS
- ECX 寄存器的特殊用途是什么?
- 默认的循环计数器寄存器。
- 字符串操作指令的计数寄存器。
3. 64位x86-64处理器
- 64位操作模式: x86-64架构引入了IA-32e模式,包括兼容模式和64位模式。
- 基本64位执行环境:
- 通用寄存器: 64位模式下,有16个64位通用寄存器,可以使用REX前缀扩展操作数大小。
- 状态标志寄存器: 64位模式下,EFLAGS寄存器被RFLAGS寄存器取代,但只使用低32位。
- 指令指针寄存器: 64位模式下,EIP寄存器被RIP寄存器取代。
- 特殊寄存器: 64位模式下,MMX和XMM寄存器数量增加,用于多媒体处理。
4. 典型x86计算机组件
- 主板: 集成了CPU、芯片组、内存、I/O接口和扩展插槽等组件。
- 芯片组: 一组处理器芯片,负责连接CPU和其他系统设备,并提供各种功能。
- 内存: 包括ROM、EPROM、DRAM、SRAM、VRAM和CMOS RAM等类型,用于存储程序和数据。
- I/O端口: 用于连接外部设备,例如并行端口、串行端口和USB端口。
- 通用设备接口: 例如PCI和PCI Express总线,用于连接各种设备。
5. 输入输出系统 - I/O访问层次: 应用程序通过调用库函数、操作系统函数、BIOS函数或直接访问硬件端口来实现I/O操作。
- 设备驱动程序: 允许操作系统与硬件设备直接通信。
- 多层次编程: 汇编语言程序可以选择不同的I/O访问层次,以实现不同的控制级别和可移植性。
总结:
本章介绍了x86汇编语言背后的硬件基础,包括CPU架构、内存管理、I/O系统等。理解这些概念对于编写高效的汇编代码至关重要。