8. 汇编语言快速查阅
文章目录
- 8. 汇编语言快速查阅
- 常用资料
- 寄存器含义
- 标志寄存器的含义
- Debug的使用
- 汇编语法
本章列出一些需要经常查阅的知识点。
常用资料
-
参考视频:烟台大学贺利坚老师的网课《汇编语言程序设计系列专题》,或者是B站《汇编语言程序设计 贺利坚主讲》,大家一起看比较热闹。
-
中文教材:《汇编语言-第3版-王爽》(课程使用)、《汇编语言-第4版-王爽》(最新版)。
-
老师的博客:《迂者-贺利坚的专栏-汇编语言》
-
检测点答案参考:《汇编语言》- 读书笔记 - 各章检测点归档
-
《汇编语言指令大全》(Github、我的百度网盘)——根据字母表排序。
-
《BIOS和DOS中断大全—中国科学技术大学》,另外我加上了目录。
寄存器含义
8086CPU中的16个寄存器:
- 通用寄存器:AX(ah/al)、BX(bh/bl)、CX(ch/cl)、DX(dh/dl)
- 变址寄存器:SI、DI
- 指针寄存器:SP、BP
- 指令指针寄存器:IP
- 段寄存器:CS、SS、DS、ES
- 标志寄存器:PSW
其中
- CS:IP 表示要执行的指令地址
- SS:SP 表示栈指针所在地址
标志寄存器的含义
本节介绍8086CPU中的标志寄存器 FLAGS,也称为程序状态字。标志寄存器可用于存储相关指令的某些执行结果、为CPU执行相关指令提供行为依据、控制CPU的相关工作方式等。FLAGS 寄存器是按位起作用的,也就是说,它的每一位都有专门的含义,记录特定的信息。有含义的位如下图所示:
标志位 | 含义 | 值为1 | 值为0 |
---|---|---|---|
OF | 溢出标志(Overflow Flag) | OV(Overflow) | NV(No Overflow) |
DF | 方向标志(Direction Flag) | DN(Down) | UP |
IF | 中断标志(Interrupt Flag) | EI(Enable Interrupts) | DI(Disable Interrupts) |
TF | 陷阱标志(Trap Flag) | - | - |
SF | 符号标志(Sign Flag) | NG(Negative) | PL(Positive) |
ZF | 零标志(Zero Flag) | ZR(Zero) | NZ(Not Zero) |
AF | 辅助进位标志(Auxiliary Carry Flag) | AC(Auxiliary Carry) | NA(No Auxiliary carry) |
PF | 奇偶标志(Parity Flag) | PE(Parity Even) | PO(Parity Odd) |
CF | 进位标志(Carry Flag) | CY(Carry) | NC(No Carry) |
- OF-溢出标志(Overflow Flag):将运算当作有符号数运算,若结果溢出则OF=1、无溢出则OF=0。
- DF-方向标志(Direction Flag):在串处理指令中,控制每次操作后si,di的增减。具体见“5.14节-DF标志和串传送指令”。
- IF-中断标志(Interrupt Flag):控制硬件中断的响应。1表示启用硬件中断,CPU可以响应由外部设备产生的中断请求;0禁用硬件中断,CPU忽略外部设备的中断请求。示例见“6.13节-外设连接与中断-sti/cli”。
- TF-陷阱标志(Trap Flag):控制单步调试。1启用单步模式,每执行一条指令后,CPU会产生一个单步中断(INT 1),允许调试程序检查CPU状态;0禁用单步模式,CPU正常执行指令,不会在每条指令后产生中断。详见“6.8节-单步中断”。
- SF-符号标志(Sign Flag):运算指令执行后,将结果视为有符号数(补码),结果为负数则SF=1、非负数则SF=0。
- ZF-零标志(Zero Flag):运算指令执行后,计算结果是否为0。结果为0则ZF=1、结果非0则ZF=0。
- AF-辅助进位标志(Auxiliary Carry Flag):用于在二进制运算过程中检测从低四位(即低半字节)到高四位(高半字节)的进位或借位情况。它主要用于支持BCD(Binary-Coded Decimal,二进制编码十进制)运算。1表示低四位有向高四位的进位/借位,0表示没有。
- PF-奇偶标志(Parity Flag):运算指令执行后,结果的所有二进制位中1的个数。偶数则PF=1,奇数则PF=0。
- CF-进位标志(Carry Flag):将运算当作无符号数运算,有向更高位的进位或借位则CF=1、没有则CF=0。
注:OF和CF在含义上几乎一致,但是OF针对有符号数运算、CF针对无符号数运算。
注:有符号数(补码)运算后,双符号位不同则为“溢出”;无符号数计算后,超出范围为“溢出”。——《计算机组成原理》
注:无符号数运算时,SF的值没有意义,但是运算结果仍然会影响SF。
在8086CPU的指令集中,影响标志寄存器的大都是运算指令,进行逻辑或算术运算;比如 add
、sub
、mul
、div
、inc
、or
、and
等。对标志寄存器没有影响的大都是传送指令,比如 mov
、push
、pop
等。使用一条指令的时候,要注意这条指令的全部功能,其中包括执行结果对标记寄存器的哪些标志位造成影响。最后给出直接访问标志寄存器的方法:
pushf
:将标志寄存器的值压栈。popf
:从栈中弹出数据,送入标志寄存器中。- debug模式下,直接使用
r
指令可以查看标志寄存器的值。注:
inc
不会影响进/借位标志位CF。
Debug的使用
更详细见“2.5节-Debug的使用”。
正常指令:
- r:查看寄存器。
- a:直接在内存中写入汇编指令。
- u:将机器指令翻译成汇编指令。
- d:查看内存数据。
- e:覆写内存数据。
- q:退出debug。
调试相关指令:
- t(Trace):逐条指令执行,适合详细调试每个指令,相当于“单步执行-步进”
- p(Procedure step):逐过程执行,适合调试过程中不想深入子过程,相当于“单步执行-步出”。比如会跳过循环。
- g(Go):连续执行程序,适合运行程序到下一个断点或结束,也可以运行到指定地址。
汇编语法
- 数字没有后缀时,默认为十进制。比如
mov ax,12
就是十进制的12,而非 0012H。 - 数据不能以字母开头,若有需要则需在前面加0。比如
mov ax,0ffffH
。 - 为防止编译错误,对于指令
mov al,[idata]
,最好加上段前缀,比如mov al,ds:[idata]
。 dw
定义一个字、db
定义一个字节、dd
定义一个双字。- 第一条指令标号约定俗成为
start
,也可以换成别的字符,比如begin
。 - 每个循环的标号命名不能相同。
- 汇编程序至少包含一个段,也就是代码段,所以无需给 CS 初始化赋值。但是其他段的段寄存器都需要初始化。
- …