汇编语言笔记(2) 80x86计算机组织

3k words

80x86微控制器

80x86微处理器系列是由英特尔公司开发的一系列相关的微处理器,其中8086是该系列的首款产品,发布于1978年。

80x86 通常指的是以8086为基础的整个微处理器家族,这包括了从8086延伸出的各种处理器,如80286、80386、80486等。这些处理器在基本的指令集架构上是向后兼容的。这一系列处理器通常被称为x86架构。

在这门课中我们主要关心的是8086型号,它的字长是16位,数据总线、外部总线宽度也是16位,地址总线宽度20位。

中央处理机

中央处理机,也就是常说的计算机的核心部件——中央处理单元,CPU(Central Processing Unit)。

它通常由控制单元、算术逻辑单元(ALU)、寄存器和高速缓存组成。

80x86寄存器组

img

通用寄存器

如上图,AX,BX,CX,DX可以称为数据寄存器,用来暂时存放计算过程中所用到的操作数、结果和其他信息。他们都可以可以既以字(16位)访问,也可以以字节(8位)访问。也就是说可以单独访问高位字节或低位字节。

这4个寄存器都是通用寄存器,但又可以用于各自的专用目的。

AX - 累加寄存器(Accumulator),可以分为AH(高位字节)和AL(低位字节)。这个寄存器常被用作算术运算的累加器。另外所有的IO指令都通过这个寄存器与外部设备传送信息。

BX - 基址寄存器(Base),可以分为BH(高位字节)和BL(低位字节)。用于基于偏移的地址计算,尤其在使用指针时。

CX - 计数寄存器(Count),可以分为CH(高位字节)和CL(低位字节)。这个寄存器经常被用于保存计数值,例如移位指令、循环或字符串操作的次数控制。

DX - 数据寄存器(Data),可以分为DH(高位字节)和DL(低位字节)。做双字长运算的时候可以和AX组合起来存放双字长数,DX用来存放高位字。也可以在IO操作时存放IO端口地址。

SP, BP, SI, DI四个16位寄存器可以像数据寄存器一样在运算过程中存放操作数。但是只能以字(16位)为单位使用。更常用的是在存储器寻址时,提供偏移地址,因此可以称为指针或变址寄存器

SP(Stack Pointer) 是用来指向程序堆栈顶部的寄存器。在8086中,堆栈是一种特殊的数据结构,主要用于存储临时数据、返回地址、局部变量等。每当进行函数调用或返回,以及推送(PUSH)或弹出(POP)数据时,SP会自动调整以指向当前的堆栈顶部。

BP(Base Pointer) 主要用于基于堆栈的高级语言编程,尤其是在管理函数内的局部变量和参数时。在复杂的函数调用中,BP可以提供一个固定的参照点,使得无论SP如何变化,程序员都可以稳定地访问所有的局部变量和参数。

SI(Source Index)DI(Destination Index) 寄存器通常在字符串和数组处理中使用。它们被用于指定数据源和目标的内存地址。

  • SI 通常用于指向要读取数据的内存位置。
  • DI 则用于指向将数据写入的内存位置。

专用寄存器

在8086架构中,除了常用的通用寄存器和指针、索引寄存器外,还有一些专用寄存器扮演着特定的角色,如IP(指令指针寄存器)、SP(堆栈指针寄存器)以及FLAGS寄存器。这些寄存器对于处理器的操作和程序的执行至关重要。

IP(Instruction Pointer) 寄存器存储着下一条要执行的指令的偏移地址。在程序执行过程中,IP寄存器与CS(代码段寄存器)共同决定了当前执行指令的完整地址。具体来说,实际的指令地址由CS寄存器的内容乘以16(左移4位)再加上IP寄存器的内容计算得出。每当CPU执行完一条指令后,IP自动更新为下一条指令的地址。

SP(Stack Pointer) 已在前面详细讨论过。简而言之,SP用于管理程序的堆栈,它指向当前堆栈顶部的内存地址。在进行函数调用、返回和其他需要临时存储数据的操作时,SP是不可或缺的。

FLAGS寄存器 存储当前的状态标志和控制标志,这些标志为CPU提供了执行指令所需的额外信息,并反映了最近操作的结果。FLAGS寄存器中的标志位包括:

  • CF(进位标志 Carry Flag):在算术操作中,当最高位产生进位或借位时,此标志被设置。
  • ZF(零标志 Zero Flag):当操作的结果为零时,此标志被设置。
  • SF(符号标志 Sign Flag):反映结果的符号,如果结果为负,此标志被设置。
  • OF(溢出标志 Overflow Flag):在有符号运算中,当结果超出目标数据类型的表示范围时,此标志被设置。
  • DF(方向标志 Direction Flag):控制字符串操作指令的处理方向,向上或向下。
  • IF(中断允许标志 Interrupt Enable Flag):控制是否响应可屏蔽中断。

段寄存器

段寄存器用于支持处理器的分段内存管理机制,这种机制允许CPU访问一个较大的地址空间,并提供了一定程度的内存保护。8086处理器有四个主要的段寄存器:CS、DS、SS和ES。每个段寄存器在程序运行中发挥着不同的角色。

CS(Code Segment) 寄存器包含当前正在执行的代码段的基地址。代码段存储计算机程序的执行代码。在程序运行时,指令指针(IP)与CS协同工作,形成完整的指令地址。因此,CS和IP一起决定了下一条要执行的指令的确切位置。

DS(Data Segment) 寄存器包含程序数据段的基地址。数据段用于存储程序中的全局变量和静态变量。大多数指令默认使用DS作为访问内存数据的段寄存器,除非明确指定其他段寄存器。

SS(Stack Segment) 寄存器包含堆栈段的基地址。堆栈段用于存储程序运行中的临时数据,如函数调用时的返回地址、局部变量和参数。堆栈指针(SP)和基指针(BP)通常与SS配合使用来管理函数调用和返回过程中的数据。

ES(Extra Segment) 寄存器最初设计用于为具有特殊存储需求的程序提供额外的段基地址。在进行某些数据传输操作时,ES可用于指定一个额外的数据源或目标地址,如字符串和数组操作等。

存储器

存储单位的地址和内容

(没什么重要的,主要就是低位字节存入低地址,高位字节存入高地址。)

实模式存储器寻址

总线宽度为 2020 位,最大寻址空间是

220=1M(Byte)2^{20}=1M(Byte)

这就是实模式下的最大寻址空间。

实模式要解决一个问题:如何在16位字长的机器中提供20位地址。

分段

用一个16位的段地址和一个16位的偏移地址来构成一个20位的地址。

机器规定:从0地址开始,每16个字节为一小段。例如,00000,00001,…,0000E,0000F,这些为一个小段;00010,00011,…,0001E,0001F,这些为另一个小段。

首地址:上述的,00000、00010,这就是每个小段的首地址。

在1MB的存储器中,每个存储单位都有唯一的一个20位地址,称为该单元的物理地址。用一个16位的段地址和一个16位的偏移地址来构成一个20位的物理地址。其中,短地址是每一段的起始地址,也就必定是小段的首地址。因此最后一个Hex(4位),必定是0,而不是1,也不会是A、F之类的。这就可以规定段地址只取段起始地址的高16位值。偏移地址则是段内相对段起始地址的偏移值。

image-20240918014856667

段寄存器

代码段寄存器CS、数据段寄存器DS、堆栈寄存器SS、附加段寄存器ES