8086汇编学习笔记

10/20/2023 4:46:11 PM
840
0

通用寄存器

8086CPU的所有寄存器都是16位的, 可以存放2个字节. AX, BX, CX, DX这4个寄存器通常用来存放一般性的数据, 被称为通用寄存器

为了兼容上一代8位寄存器.AX, BX, CX, DX这4个寄存器可以分为两个独立的8位寄存器来使用

  1. AX -> AH + AL 低8位构成AL, 高8位构成AH
  2. BX -> BH + BL
  3. CX -> CH + CL
  4. DX -> DH + DL

段寄存器

8086cpu有4个段寄存器: CS, DS, SS, ES,各自扮演了特定的角色。

1. CS(代码段寄存器):Code Segment register,是用来存储执行指令的段的基地址。当8086在运行时,会使用CS:IP来构造实际的物理地址来获取需要执行的指令。

2. DS(数据段寄存器):Data Segment register,它被用来存储处理器正在处理的数据段的基地址。当处理器需要处理数据(读取或者写入)时,会用DS和有效地址结合生成实际的物理地址。

3. SS(堆栈段寄存器):Stack Segment register,是用于存储当前使用的堆栈的基地址。当进行堆栈操作(比如PUSH或POP)时,会用SS与堆栈指针(SP)组成实际的物理地址。

4. ES(附加段寄存器):Extra Segment register,是一个附加的数据段寄存器,通常在需要进行一些数据拷贝和转移的操作(例如字符串操作)时用到,用于存储源/目标数据的段基地址。

以上所有的段寄存器都用于确定不同类型内存操作的物理地址。因为在8086中,实际的物理地址 = 段寄存器 * 16 + 有效地址,因此段寄存器的存在及其重要,对于了解8086构造物理地址的方式、理解整个存储器的结构和运行特性具有很大的帮助。

  1. CS和IP是8086CPU中两个最关键的寄存器, 它们指示了CPU当前要读取的指令地址. CS是段寄存器, IP为指令指针寄存器
  2. 任意时刻,CPU将CS:IP指向的内容当做指令执行

寻址能力

在8086内部,能够一次性处理, 传输, 暂时存储的信息最大长度是16位. 8086cpu有20位地址总线, 可以传送20位地址, 达到1MB的寻址能力.

  1. cpu中相关部件提供2个16位地址, 段地址+偏移地址
  2. 段地址和偏移地址通过内部总线送入一个称为地址加法器的部件
  3. 地址加法器将两个16位地址合成一个20位的物理地址
  4. 地址加法器通过内部总线将20位物理地址送入输入输出控制电路
  5. 输入输出控制电路将20位物理地址送上地址总线
  6. 20位物理地址被地址总线传送到存储器

示例1

计算ffff:0006单元中的数乘以3, 结果存在dx中

 assume cs: code

code segment

mov ax,0ffffh     ;在汇编源程序中,数据不能以字母开头,所以要在前面加0
mov ds,ax         ;设置数据段地址的起始地址为,offff
mov bx,6          ;以上,设置ds:bx指向ffff:6 ,设置偏移地址,偏移量为6

mov al,[bx]       ;从内存地址ffff:6中取出数去到al中,[BX]表示的是一个内存地址,具体的地址值存储在BX寄存器中。意思是从内存中读取一个数据到AL寄存器
mov ah,0          ;以上,设置(al)=((ds*16) + (bx)), (ah)=0 ,因为第一句ah=FF,所以在这里将ah设置为0

mov dx,0          ;累加寄存器清0
mov cx,3          ;循环3次,用与loop循环计数器

s: add dx,ax      ;ax既 ah+al的值
   loop s         ;以上,累加计算(ax)*3,从ax取值与dx内容相加,共进行3次+ax的操作,应注意:ax内的值是16进制的

mov ax,4c00h
int 21h           ;程序返回

code ends

end

示例2

利用栈, 将程序中定义的数据逆序存放


assume cs:codesg
codesg segment
       ;dw 定义的数据偏移地址从0开始,地址段属于cs地址段  cs:0 开始
  dw 0123h, 0456h, 0789h, 0abch, 0defh, 0fedh, 0cbah, 0987h
  dw 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
                            ; 用dw定义16个字型数据,在程序加载后,将取得16个字的内存工具
                            ; 在后面的程序中将这段空间当做栈来使用

  start: mov ax,cs          ;取出cs的初始地址
         mov ss,ax          ;cs的初始地址放在ss中
         mov sp,30h         ; 将设置栈顶ss:sp指向cs:30,dw定义了24个字空间,共计48个字节,48=30h

         mov bx,0           ;累加器,用于计算数据栈地址偏移量
         mov cx,8           ;loop计数器,循环8次

    s0: push cs:[bx]        ;
        add bx,2
        loop s0             ;以上将代码段0~15单元总的8个字型数据依次入栈

        mov bx,0

    s1: pop cs:[bx]
        add bx,2
        loop s1             ;以上依次出栈8个字型数据到代码段0~15单元中

  mov ax,4c00h
  int 21h

codesg ends
end start                   ;指明程序的入口在start处

 8086汇编程序中,什么时候用 cs,IP, SS, SP, BP, SI, DI, DS, ES这些寄存器?

在8086汇编编程中,这些寄存器具有不同的用途:

  1.  CS(代码段寄存器):这个寄存器包含当前正在执行的代码的段地址。当指令被装入并执行时,处理器自动更新指令指针(IP)。因此,任何时候CS:IP都指向下一条要执行的指令地址。
  2. IP(指令指针寄存器):和CS配合使用,IP寄存器保存了代码段内下一条要执行的指令的偏移地址。CS和IP一起形成了完整的物理地址。
  3. SS(堆栈段寄存器):用来指向存放堆栈的内存区块的头部。这个寄存器通常在函数调用、中断处理和数据压栈/弹栈操作中发挥作用。此寄存器用于指向当前使用的堆栈的基址。它通常与SP寄存器一起使用,以处理堆栈操作。
  4. SP(堆栈指针寄存器):指向堆栈顶部的下一未使用位置,通常和SS寄存器配合使用。
  5. BP(基址指针寄存器):一般用于基于堆栈的变量访问。BP寄存器可以定位到函数/过程的参数和局部变量。此寄存器主要用于基于堆栈的数据访问,通常在调用子程序时保存SP寄存器的值。它还允许更容易地访问调用堆栈中的参数和局部变量。
  6. SI(源索引寄存器)和DI(目标索引寄存器):通常在字符串和数组操作中使用,比如复制和初始化等。它是一个源指数寄存器,通常与DS寄存器一起用作复制/传输指令的源地址。
  7. DI (Destination Index):它是一个目的指数寄存器,通常与ES寄存器一起用作复制/传输指令的目标地址。
  8. DS(数据段寄存器):含有大部分程序运行时读取或存储的变量和数据的地址。此寄存器主要用于处理数据操作。在使用数据数组或变量时,通常会保留数据段的地址。
  9. ES(额外段寄存器):通常配合DI寄存器在一些字符串操作中使用,比如字符串传输和查找。这是一个额外的分段寄存器,通常作为目标分段寄存器,用于字符串和一些数据传输操作。
  10. 以上的使用情况只是最常见的一些,它们也可以用于一些特殊的目的,取决于程序的具体需求。
assume cs:code,ds:data,ss:stack

data segment
  dw 0123h,0456h
data ends

stack segment
  dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
stack ends


code segment
  start: mov ax,stack     ;栈地址给ax
         mov ss,ax        ;栈地址放到ss中,ss寄存器寄存器用于指向当前使用的堆栈的基址。它通常与SP寄存器一起使用,以处理堆栈操作
         mov sp,16        ;此寄存器一般与SS寄存器一起使用,以维护堆栈指针。它指向当前堆栈的顶部

         mov ax,data      ;data数据段地址给ax
         mov ds,ax        ;data数据段的地址送到ds段寄存器中。此寄存器主要用于处理数据操作。在使用数据数组或变量时,通常会保留数据段的地址。

         push ds:[0]
         push ds:[2]

         pop ds:[2]
         pop ds:[0]

         mov ax,4c00h                   
         int 21h
code ends

end start

 

全部评论



提问