8086汇编——Introduction

8086汇编——Introduction

一、8086CPU的三种工作模式

  1. 实模式:只有低20位地址线起作用,仅能寻址第一个1MB的内存空间。MS DOS运行于该模式下。
  2. 保护模式:在该模式下,机器可提供虚拟存储的管理和多任务的管理机制。Windows 9x/NT/2000运行与该模式下。
  3. 虚拟8086模式:同时模拟多个8086处理器的工作。

二、8086微机系统的组成

对于汇编程序而言,我们需要关心CPU中的寄存器、存储器地址、端口(I/O地址)。

【内存单元的两个元素】: 地址(编号)和值(内容)。

【字节、字、双字】
多字节数据在存储器中占连续的多个存储单元。低位字节存入低地址,高位字节存入高地址。

字节:8086的内存以字节编址,每个内存单元有唯一的地址(物理地址),可以存放一个字节。
:一个字占据两个连续的字节。
双字:双字占据两个连续的字。

以低地址表示多字节数据存储的位置。

【数据的地址对齐】
字单元安排在偶地址(xxx0B),双字单元安排在模4地址(xx00B)等。

对于非对齐地址的数据,处理器访问时需要多次访问存储器,这样做花费时间较多。

【总线】
8086的系统总线有3种:

  1. 数据总线
  2. 地址总线:8086CPU外部一共有20条地址总线,但在CPU内部一次只能传送16位地址。
  3. 控制总线

【I/O】
I/O地址叫做端口,通常采用十六进制数来表达端口:

  • 8086的I/O端口为16位,可支持64k个8位端口;
  • I/O地址范围为:0000H ~ FFFFH

【8086的功能结构】

  • 总线接口单元BIU:主要负责读取指令和操作数。
  • 执行单元EU:主要负责指令译码和执行。

三、汇编语言程序、汇编程序、连接程序、调试程序

汇编程序:汇编程序将汇编语言源程序翻译(或称作“汇编”)成机器代码目标模块。
.ASM -> .OBJ

注意区分汇编程序与汇编语言源程序。

连接程序:连接程序将汇编后的目标模块转换为可执行程序。

调试程序:调试程序以便排错、分析等。

四、寄存器组

执行单元EU有8个通用寄存器。其中包含1个指令指针寄存器,1个标志寄存器,4个段寄存器。

【16位通用寄存器】
AX、BX、CX、DX、SI、DI、BP、SP
其中AX、BX、CX、DX可以分作高8位和低8位的两个独立寄存器。如:AH和AL。我们对其中8位的操作,并不影响另外对应的8位数据。

1、数据寄存器ax、bx、cx、dx
数据寄存器用来存放计算的结果和操作数,也可以存放地址。
每个寄存器又有它们各自的专用目的。

  • AX——累加器,使用频度最高,用于算术、逻辑运算以及与外设传送信息等;
  • BX——基址寄存器,常用做存放存储器地址;
  • CX——计数器,作为循环和串操作等指令中的隐含计数器;
  • DX——数据寄存器,常用来存放双字长数据的高16位,或存放外设端口地址。

2、变址寄存器si、di
变址寄存器常用于存储器寻址时提供地址

  • SI是源变址寄存器
  • DI是目的变址寄存器
    串操作类指令中,SI和DI具有特别的功能

3、指针寄存器sp、bp
指针寄存器用于寻址内存堆栈内的数据

  • SP为堆栈指针寄存器,指示栈顶的偏移地址。
    SP不能再用于其他目的,具有专用目的。SP始终指向栈顶。
  • BP为基址指针寄存器,表示数据在堆栈段中的基地址。

SP和BP寄存器与SS段寄存器联合使用以确定堆栈段中的存储单元地址

4、堆栈
8086中堆栈通常有处理器自动维持,由堆栈段寄存器SS和堆栈指针寄存器SP共同指示。

5、指令指针寄存器IP
指示代码段中指令的偏移地址。与代码段寄存器CS连用(CS:IP)。

6、标志寄存器
标志(flag)用于反映指令执行结果或控制指令执行形式。

16位的标志寄存器——程序状态字PSW寄存器。

状态标志(6个)——用来记录程序运行结果的状态信息,许多指令的执行都将相应地设置它。
CF ZF SF PF OF AF

控制标志(3个)——可由程序根据需要用指令设置,用于控制处理器执行指令的方式。
DF IF TF

  1. 进位标志CF(Carry Flag):当运算结果的最高有效位有进位(加法)或借位(减法)时,CF=1,or CF=0;

  2. 零标志位ZF(Zero Flag):若运算结果为0时,ZF=1,or ZF=0;

  3. 符号标志位SF(Sign Flag):运算结果最高位为1,则SF=1,or SF=0。
    有符号数据用最高有效位表示数据的符号。所以,最高有效位就是符号标志的状态
  4. 奇偶标志位PF(Parity Flag):当运算结果最低字节中“1”的个数为零或偶数时,PF=1;or PF=0。
    PF标志仅反映最低8位中“1”的个数是偶或奇,即使是进行16位字操作。

5.溢出标志OF(Overflow Flag):若算术结果有溢出,OF=1,or OF=0;【什么是溢出?溢出判断】

6.辅助进位标志AF(Auxiliary Carry Flag):运算时D3位(低半字节)有进位或借位时,AF=1,or AF=0。这个标志主要由处理器内部使用,用于十进制算术运算调整指令中,用户一般不必关心。

7.方向标志DF(Direction Flag):用于串操作指令中,控制地址的变化方向:

  • 设置DF=0,存储器地址自动增加;
  • 设置DF=1,存储器地址自动减少。
  • CLD指令复位方向标志:DF=0;
  • STD指令置位方向标志:DF=1。

8.中断允许标志IF(Interrupt-enable Flag):用于控制外部可屏蔽中断是否可以被处理器响应:

  • 设置IF=1,允许中断;
  • 设置IF=0,禁止中断。
  • CLI指令复位中断标志:IF=0;
  • STI指令置位中断标志:IF=1。

9.陷阱标志TF(Trap Flag):用于控制处理器进入单步操作模式:

  • 设置TF=0,处理器正常工作;
  • 设置TF=1,处理器单步执行指令。
    单步执行指令——处理器在每条指令执行结束时,便产生一个编号为1的内部中断。这种内部中断称为单步中断。所以TF也称为单步标志。

7、段寄存器
段地址——段的起始地址的高16位地址。段内再由16位二进制数来寻址。
偏移地址——段内存储单元到段首地址的字节的距离。
物理地址——用20位二进制数表示。地址范围为00000H ~ FFFFFH。物理地址唯一标识一个存储单元。
逻辑地址——段地址:偏移地址,逻辑地址不唯一。
物理地址=段地址x16+偏移地址

8086有4个16位的段寄存器。

  1. 代码段CS(Code Segment):指明代码段的 起始地址。
    代码段用来存放程序的指令序列。指令指针寄存器IP指示下一条指令的偏移地址。处理器利用CS:IP取得下一条要执行的指令。

  2. 堆栈段SS(Stack Segment):指明堆栈段的起始地址。
    堆栈段确定堆栈所在的主存区域。堆栈指针寄存器SP指示堆栈栈顶的偏移地址。处理器利用SS:SP操作堆栈栈顶的数据。

  3. 数据段DS(Data Segment):指明数据段的起始地址。
    数据段存放运行程序所用的数据。各种主存寻址方式(有效地址EA)得到存储器中操作数的偏移地址。处理器利用DS:EA存取数据段中的数据。

  4. 附加段ES(Extra Segment):指明附加段的起始地址。
    附加段是附加的数据段,也用于数据的保存。各种主存寻址方式(有效地址EA)得到存储器中操作数的偏移地址。处理器利用ES:EA存取附加段中的数据。
    串操作指令将附加段作为其目的操作数的存放区域。

【关于分段】

  1. 8086对逻辑段的要求:
  • 段地址低4位均为0
  • 每段最大不超过64KB(216 B),但并不要求必须为64KB
  • 各段之间可以独立,也可以有重叠
  1. 如何分配各个逻辑段
  • 程序的指令序列必须安排在代码段。
  • 程序使用的堆栈一定在堆栈段。
  • 程序中的数据默认是安排在数据段,也经常安排在附加段,尤其是串操作的目的区必须是附加段。
  • 数据的存放比较灵活,实际上可以存放在任何一种逻辑段中。

8、段超越前缀指令
没有指明时,一般的数据访问在DS段;使用BP访问主存,则在SS段
默认的情况允许改变,需要使用段超越前缀指令;8086指令系统中有4个,用于明确指定数据所在的逻辑段:
CS: ;代码段超越,使用代码段的数据
SS: ;堆栈段超越,使用堆栈段的数据
DS: ;数据段超越,使用数据段的数据
ES: ;附加段超越,使用附加段的数据

【段超越示例】

【不允许使用段超越的情况】

  • 串处理指令的目的串必须用ES段;
  • PUSH指令的目的和POP指令的源必须用SS段;
  • 指令必须存放在CS段。

【段寄存器的使用规定】

【补充】

【什么是溢出】
处理器内部以补码表示有符号数。8位表达的整数范围是:+127~-12816位表达的范围是:+32767~-32768。如果运算结果超出这个范围,就产生了溢出。有溢出,说明有符号数的运算结果不正确。

【溢出和进位】
溢出标志OF和进位标志CF是两个意义不同的标志。
进位标志表示无符号数运算结果是否超出范围,运算结果仍然正确
溢出标志表示有符号数运算结果是否超出范围,运算结果已经不正确

【如何运用溢出和进位】

  • 处理器对两个操作数进行运算时,按照无符号数求得结果,并相应设置进位标志CF;同时,根据是否超出有符号数的范围设置溢出标志OF。

  • 应该利用哪个标志,则由程序员来决定。也就是说,如果将参加运算的操作数认为是无符号数,就应该关心进位;认为是有符号数,则要注意是否溢出。

【溢出判断】
判断运算结果是否溢出有一个简单的规则:

  • 只有当两个相同符号数相加(包括不同符号数相减),而运算结果的符号与原数据符号相反时,产生溢出;因为,此时的运算结果显然不正确。

  • 其他情况下,则不会产生溢出。

猜你喜欢

转载自blog.csdn.net/pilifeng1/article/details/81842326