讀書筆記《組合語言》——intel8086暫存器的記憶體訪問

Ho1aAs發表於2020-12-25

學習教材:《組合語言(第3版)》王爽著

一、記憶體中字的儲存

CPU中一個字寄存在一個十六位暫存器中。其中:高八位存放高位位元組,低八位存放低位位元組

字單元由兩個連續單元組成,起始地址為N的字單元稱為N地址字單元,N地址單元由地址為N和N+1兩個單元構成

在這裡插入圖片描述

  • 0地址單元中存放的位元組型資料是11H
  • 0地址字單元中存放的字型資料是2211H(注意順序)(地址單元地址字單元
  • 1地址字單元中存放的字型資料是3322H

二、記憶體地址暫存器

記憶體地址由段地址和偏移地址組成,DS暫存器用來存放段地址偏移地址由[…]表示

mov bx,1000H
mov ds,bx
mov al,[0]

指令執行時,CPU自動取DS內的資料作為段地址,最終將10000H(1000:0)中的資料送入了al

由上所示,CPU不支援將資料直接送入DS暫存器,需要將地址資料先送入一個普通暫存器(即上方的bx),再將普通暫存器中的地址資料傳入DS段暫存器

實驗:寫出下面的命令執行後記憶體中的值

在這裡插入圖片描述

mov ax,1000H  //ax=1000H
mov ds,ax  	  //ds=1000H
mov ax,2C34H  //ax=2C34H
  • List item

    mov [0],ax //&10000H=2CH, &10001H=34H
    mov bx,[0] //bx=2C34
    sub bx,[2] //bx=2C34H-1122H=1B12H
    mov [2],bx //&10002H=12H, &10003H=1BH

最終10000H-10003H為:34、2C、12、1B

三、mov、sub、add指令

mov支援的操作

  • mov 暫存器,資料
  • mov 暫存器,暫存器
  • mov 暫存器,段暫存器
  • mov 暫存器,記憶體單元
  • mov 記憶體單元,暫存器
  • mov 記憶體單元,段暫存器
  • mov 段暫存器,記憶體單元
  • mov 段暫存器,暫存器

用mov指令訪問記憶體單元可以只給出偏移地址,段地址預設存放在ds暫存器中

add、sub支援的操作

  • add(sub) 暫存器,資料
  • add(sub) 暫存器,暫存器
  • add(sub) 暫存器,記憶體單元
  • add(sub) 記憶體單元,暫存器

暫存器的清零

要清零暫存器,可以用mov置零或是sub自減。區別在於sub ax,ax的機器碼是二位元組,而mov ax,0的機器碼是三位元組

四、棧

棧有兩種基本操作:入棧和出棧,操作規則為LIFO(Last In First Out,後進先出),且這兩種操作都是以字為單位進行,對應指令為push與pop。

首先入棧的存入最高位字單元
在這裡插入圖片描述

五、棧地址暫存器

當我們將某一段記憶體當作棧來使用時,CPU是如何知道這段地址是棧呢?

8086CPU中有兩個暫存器段暫存器SS和暫存器SP,SS存有棧頂段地址,SP存有偏移地址。任意時刻,SS:SP指向棧頂元素
在這裡插入圖片描述
如同DS,SS也不支援直接傳入資料,需要普通暫存器作為中轉

空棧時

若棧空,SP會指向棧最高地址單元的下一個地址

在這裡插入圖片描述

六、push、pop指令

支援的操作

注意:以字為單元

  • push(pop) 暫存器
  • push(pop) 段暫存器
  • push(pop) 記憶體單元

例如:

mov ax,1000H
mov ds,ax
push [0]
pop [2]

push ax的執行

  1. SP-=2,SS:SP指向當前棧頂前面的單元,成為新棧頂
  2. 將ax的內容送入新棧頂

pop ax的執行

  1. 將SS:SP指向的資料送入ax,即當前棧頂值送入ax
  2. SP+=2,SS:SP指向當前棧頂下面的單元,成為新棧頂
    在這裡插入圖片描述

七、棧頂越界問題

對滿棧進行入棧、對空棧進行出棧都會導致棧頂超出了棧空間,引起棧頂超界問題

棧頂超界是危險的,可能會導致棧外的重要資料、程式碼被以外改寫,引發不可預料的錯誤

8086CPU不保證對棧的操作不會引起越界,它只知道當前棧頂的位置,而不知道棧的空間大小。因此操作棧時要人工考慮棧頂越界問題

實驗:程式設計

  1. 將10000H~1000FH作為空棧;

  2. 設定AX=001AH,BX=001BH,先後入棧;

  3. 將AX,BX清零;

  4. 從棧中恢復AX,BX的資料;

    mov ax,1000H
    mov ss,ax
    mov sp,0010H  //注意空棧的棧頂指標
    
    mov ax,001AH
    mov bx,001BH	
    push ax
    push bx
    
    sub ax,ax
    sub bx,bx
    
    pop bx
    pop ax
    

八、棧段

我們可以將長度為N(N<=64KB)的一組地址連續,起始地址是16的倍數的記憶體單元當作一個棧空間使用,從而定義了一個棧段

一段記憶體可以既是程式碼儲存空間,又可以是資料儲存空間,還可以是棧空間,也可以什麼都不是。關鍵在於CPU中暫存器的設定,即CS、IP、SS、SP、DS的設定。是因為先有了暫存器設定,才有了那段記憶體的屬性

相關文章