文章目录
前言
此篇文章主要收录《汇编语言 :基于x86处理机》的读书摘要和注解。
书籍信息:
中文名:汇编语言:基于x86处理机
英文名:Assembly Language for x86 Processors Seventh Edition
作者: Kip Irvine 基普 欧文
译者:贺莲 龚奕利
China Machine Press
基本概念
本书主要介绍与运行Microsoft Windows 32 位 和 64 位系统的Intel 和 AMD处理机兼容的微处理器编程。
配合本书应该使用MASM(Microsoft宏汇编器)VS大多数版本(专业,旗舰,精简)都包含MASM。(注:也可以在VS CODE 下载插件MASM/TASM 此插件调试界面为图形化界面)
此章后续主要讲二进制和相关运算,学过多次,跳过。
x86处理机架构
指令执行周期
一条指令不会神奇地一下就执行完成,CPU在执行一条机器指令时,需要经过一系列预先定义好的步骤。
这些步骤被称为 指令执行周期 instruction execution cycle
假设现在指令指针寄存器(instruction pointer register IP)已经有了想要的地址。下面就是执行步骤
CPU从被称为 指令队列 instruction queue 的 内存区域取得指令, 之后立即增加指令指针的值
CPU 对指令的二进制位模式进行译码。这种位模式可以会表示该指令有操作数(输入值)
如果有操作数,CPU就从寄存器和内存中取得操作数。有时,这步还包含了地址计算。
使用步骤三得到的操作数,CPU执行该指令。同时更新部分状态标志位,如零标志、进位标志。
如果输出操作数也是该指令的一部分,则CPU还需要存放其执行结果 (cmp 指令就没有输出操作数 只会更新标志位)
上述过程即下面三步
取值 Fetch
译码 Decode
执行 Execute
操作数即操作中输入或输出的值。如Z = X + Y.
有两个输入操作数 X,Y 一个输出操作数 Z。
可以看成函数的输入,输出。
读取内存
计算机从内存中读取一个值,需要经过以下步骤。
将想要读取的值的地址放到地址总线上
设置处理器RD(读取)引脚(改变RD的值)
等待一个时钟周期给存储器芯片进行响应
将数据从数据总线复制到目标操作数
上述每一步常常只需要一个时钟周期:基于处理器内固定速率时钟节拍的一种时间测量方法。
计算机CPU通常是用其时钟频率来描述。例如:速率位1.2Ghz 意味着时钟节拍或震荡为每秒12亿次。
(可以打开任务管理器 ctrl alt delete 查看相关信息)
但是相对于CPU寄存器相比,速度太慢了,所以用cache作为中间层次。
x86系列中的cache存储器有两种类型:一级存储器位于CPU上,二级存储器速度略慢,通过高速数据总线与CPU相连。
加载并执行程序
OS在当前磁盘目录下搜索程序的文件名。
如果找不到,则在预定目录列表(路径)下搜索文件名。
当OS无法检索到文件名时,它会发出出错信息
如果程序文件被找到
OS就访问磁盘目录中的程序文件基本信息:文件大小及其在磁盘驱动器上的物理位置
OS确定内存中下一个可使用的位置,将程序文件加载到内存
为该程序分配内存块,并将程序大小和位置信息加入表中
另外OS可能调整程序内指针的值,使得它们包括程序数据地址
OS开始执行程序的第一条机器指令(程序入口)
当程序开始执行后,就成为一个进程(process)
OS为这个进程分配一个标识号(进程ID):用于在执行期间对其进行追踪
进程自动追踪。OS的工作是追踪进程的执行,并响应系统资源的请求。
这些资源包括:内存、磁盘文件和输入输出设备等
进程结束后,就会从内存移除
操作模式
x86 有三种主要的操作模式:
保护模式
实地址模式
系统管理模式
以及一个子模式:
虚拟8086模式 : 保护模式的特殊情况
//建议深刻理解操作模式
保护模式 Protected Mode : 保护模式是处理器的原生状态。
在这种模式下,所有的指令和特性都是可用的。
分配给程序的独立内存区域被称为栈,而处理器会阻止程序使用自己身段范围之外的内存
处理器可以同时运行多个程序
为每个进程 运行中的程序 分配共4GB的内存
每个程序都分配有自己的保留内存区域
程序之间禁止意外访问其他程序的代码和数据
MS-Windows和Linux运行在保护模式下
虚拟8086模式 Virtual-8086 Mode : 保护模式下,处理器可以在一个安全环境中
直接执行实地址模式软件,如MS-DOS程序。
换句话说,如果一个程序崩溃了或是试图向系统内存区域写数据,都不会影响到同一时间内执行的其他程序。
现代操作系统可以同时执行多个独立的虚拟8086会话。
计算机运行在保护模式下
通过创建一个带有1MB地址空间的虚拟8086机器来模拟运行于实地址模式的80x86计算机
例如在Windows NT 和 2000下
当打开一个命令窗口时,就创建了一个虚拟8086机器
同一时间可以运行多个这样的窗口,并且窗口之间都是受到保护的
在Windows NT 2000 XP 系统中
一些需要直接使用计算机硬件的MS-DOS不能运行在虚拟8086模式下
实地址模式 Real-Address Mode : 实地址模式实现的是早期Intel处理器的编程环境。
但是增加了一些其他的特性,如切换到其他模式的功能。
当程序需要直接访问系统内存和硬件设备时,这种模式就很有用。
只能寻址1MB内存,地址从00000h到FFFFFh
处理机一次只能运行一个程序,但是可以暂时中断程序来处理来自外围设备的请求
这被称为中断 interrupt
应用程序被允许访问内存的任何位置,包括那些直接与系统硬件相关的地址
MS-DOS在实地址模式下运行,WIN95和98能够引导进入这种模式
系统管理模式 System Management Mode : 系统管理模式向OS提供了诸如电源管理和系统安全等功能的机制。
这些功能通常由计算机制造商实现的
他们为了一个特定的系统设置而定制处理器
基本执行环境
地址空间:在32位保护模式下,一个任务或者程序最大可以寻址4GB的线性地址空间。
从P6处理器开始,一种被称为 扩展物理寻址 extended physical addressing 的技术使得可以被寻址的物理内存空间增加到64GB.
与之相反,实地址模式只能寻址1MB空间。如果处理器在保护模式下运行多个虚拟8086程序,则每个程序只能拥有自己的1MB内存空间。
基本程序执行寄存器 建议全背
32位通用寄存器:主要用于算术运算和数据传输 其中abcd四个寄存器,以ax为例,可以用 ax 去访问低16位,ah,去访问ax的高8位,al去访问ax的低8位。
EAX EBX ECX EDX
EBP ESP ESI EDI
特殊用法 建议背下来 挺常用的
乘除指令默认用EAX,被称作 extended accumulator 扩展累加寄存器。
CPU默认使用ECX为循环计数器
ESP用于寻址堆栈(一种系统内存结构)数据。极少用于算术运算和数据传输。被叫做 extended stack pointer 扩展堆栈指针寄存器。
ESI 和 EDI 用于高速存储器传输指令,有时也被称为extended source index 扩展源变址寄存器。extended destination index 扩展目的变址寄存器。
高级语言通过EBP extended frame pointer 扩展帧指针 来引用堆栈中的函数参数和局部变量。处理高级编程,它一般不用于算术运算和数据传输。
16位段寄存器:实地址模式中,16位段寄存器表示的是预先分配的内存区域的基址,这个内存区域称为段。保护模式中,段寄存器中存放的是段描述符表指针。一些段中存放程序指令(代码段),另外一些段存放变量(数据段),还有一个堆栈段存放的是局部函数变量和函数参数。
CS SS DS (code segment stack segment data segment)
ES FS GS
32位寄存器:
EIP 指令指针寄存器 包含下一条将要执行指令的地址。某些机器指令能够控制EIP,使得程序分支转向到一个新位置。
EFLAGS 包含了独立的二进制位,用于控制CPU的操作,或反映CPU操作的结果。有些指令可以测试和控制这些单独的处理器标志位。(跳转指令会依靠这些处理器标志位)
控制标志位:控制标志位控制CPU的操作。例如,它们能使CPU每执行一条指令后进入中断,在侦测到算术运算溢出时中断执行;进入虚拟8086模式,以及进入保护模式。程序可以通过设置EFLAGS寄存器中的单独位来控制CPU的操作,比如,方向标志位和中断标志位。
状态标志位:状态标志位反映了CPU执行的算术与逻辑操作的结果。
进位标志位 CF 与目标位置相比,无符号算术运算结果太大时,设置该标志位
注意是无符号数
溢出标志位 OF 与目标位置相比,有符号算术运算结果太大或太小时,设置该标志位
注意是有符号数
符号标志位 SF 算术或逻辑操作产生负结果时,设置该标志位
零标志位 ZF 算术或逻辑操作产生的结果为零时,设置该标志位
辅助进位标志位 AC 算术操作在8位操作数中产生了位3向位4的进位时,设置该位。也就是说分8位后,出现进位设置该标志。
奇偶校验标志 PF 结果最低有效字节包含偶数个1时,设置该标志位。否则清除。此标志一般用于判断结果是否发生错误。
其他寄存器
MMX 寄存器:在实现高级多媒体和通信应用时,MMX技术提高了Intel处理器的性能。
8个64位MMX寄存器支持称为SIMD 单指令,多数据 Single-Instruction, Multiple-Data 的特殊指令。
XMM寄存器:x86结构还包括了8个128位XMM寄存器,它们被用于SIMD流扩展指令集。
浮点单元:FPU floating-point unit 执行高速浮点算术运算。
64位 x86-64 处理器
指令集是已讨论的x86指令集的64位扩展。
一些基本特征:
- 向后兼容x86 很重要 但是 导致指令集越来越复杂
- 地址长度为64位 但是只能现在只能使用低48位
- 可以使用64位寄存器 运行指令具有64位整数操作数
- 比x86多了8个通用寄存器
- 物理地址为48位 支持256TB的RAM
处理器运行于本机64位模式时,不支持16位实模式或虚拟8086模式。
Intel 64 引入了一个新模式:IA-32e {兼容模式,64位模式}
兼容模式:现有的16位和32位应用程序通常不用进行重新编译就可以运行。
64位模式:64位windows的原生模式。
基本64位执行环境
16个64位通用寄存器
8个80位浮点寄存器
1个64位状态标志寄存器RFLAGS 只使用低32位
1个64位指令指针寄存器RIP
具体查表吧
典型x86计算机组件
主板
一般有
- CPU插座 根据其支持的处理器类型 插座有不同的性质和尺寸
- 存储器插槽 用于直接插入小型内存条
- BIOS
- CMOS RAM
- 大容量插槽设备接口 如硬盘和CD-ROMS
- 外设的USB接口
- 键鼠接口
- PCI 总线
可以有
- 集成声音处理器
- 并行 串行设备接口
- 集成网卡
- AGP总线
内存
见计组
输入输出
应用程序 第三层
调用HLL库函数,将字符串写入标准输出。
库函数调用OS函数,传递字符串指针
OS函数 第二层
用循环的方法调用BIOS子程序,向其传递ASCII码和颜色。
调用另一个子程序,将光标移动到屏幕的下一个位置
BIOS函数 第一层
接收一个字符,将其映射到一个特定的系统字体,并把该字符发送到与视频控制卡相连的硬件端口。
硬件 第零层
为视频显示产生定时硬件信号,来控制光栅扫描并显示像素。
汇编可以从上述所有层次进行输入输出。
汇编语言基础
汇编语言以晦涩难懂而著名 但是它也是一种几乎提供了全部信息的语言
本章每次提到汇编器使用的语法规则时,实际是指MASM汇编器使用的语法规则。以下不再重复MASM这个词。
以下使用Microsoft语法符号:
方括号[ ] 内的元素表示是可选的;
大括号内的元素用 | 分割 且必须要选择一个元素
斜体字标识有明确定义或说明的元素
整数常量
[ {+ | -} ] digits [ radix ]
h 十六进制
q/o 八进制
d 十进制
b 二进制
r 编码实数
;十进制
26
;十进制
26d
;二进制
11010011b
;八进制
42q
;八进制
42o
;十六进制
1Ah
;十六进制
0A3h ;以字母开头的十六进制数 必须加前置0 放置汇编器将其解释为 标识符
() | 圆括号 | 1 |
---|---|---|
+ , - | 一元加 减 | 2 |
* / | 乘除 | 3 |
mod | 取模 | 3 |
+ - | 加减 | 4 |
数字越小,优先级越高。不过嘛,加括号就不用死记优先级了。