彙編自動出棧 組合語言入棧出棧PUSH和POP指令

2021-10-17 02:02:06 字數 3632 閱讀 1141

前面我們一直在使用push ax和pop ax,顯然push和pop指令是可以在暫存器和記憶體(棧空間當然也是記憶體空間的一部分,它只是一段可以以一種特殊的方式進行訪問的記憶體

空間。)之間傳送資料的。

push和pop指令的格式可以是如下形式:

push 暫存器 ;將乙個暫存器中的資料入棧

pop 暫存器 ;出棧用乙個暫存器接收出棧的資料

當然也可以是如下形式:

push 段暫存器 ;將乙個段暫存器中的資料入棧

pop 段暫存器 ;出棧,用乙個段暫存器接收出棧的資料

push和pop也可以在記憶體單元和記憶體單元之間傳送資料,我們可以:

push 記憶體單元 ;將乙個記憶體字單元處的字入棧(注意:棧操作都是以字為單位)

pop 記憶體單元 ;出棧,用乙個記憶體字單元接收出棧的資料

比如mov ax,1000h

mov ds,ax ;記憶體單元的段位址要放在ds中

push [0] ;將1000:。處的字壓入棧中

pop [2] ;出棧,出棧的資料送入1000:2處

指令執行時,cpu要知道記憶體單元的位址,可以在push, pop指令中只給出記憶體單元的偏移位址,段位址在指令執行時,cpu從ds中取得。

問題3.7

程式設計,將10000h-1 000fh這段空間當作棧,初始狀態棧是空的,將ax, bx, ds中的資料入棧。

分析**如下:

mov ax,1000h

mov ss,ax ;設定棧的段位址,ss=1000h,不能直接向段暫存器ss中送入

;資料,所以用ax中轉。

mov sp,0010h ;設定棧頂的偏移位址,因棧為空,所以sp=ooloh。如果

;對棧為空時sp的設定還有疑問,複習3.,節、問題3.6

;上面的3條指令設定棧頂位址。程式設計中要自己注意棧的大小。

push ax

push bx

push ds

問題3.8

程式設計(1)將1 0000h-1000fh這段空間當作棧,初始狀態棧是空的;

(2)設定ax=001 ah , bx=001 bh

(3)將ax, bx中的資料入棧;

(4)然後將ax, bx清零;

(5)從棧中恢復ax, bx原來的內容。

分析**如下:

mov ax,1000h

mov ss,ax

m0v sp,0010h ;初始化棧頂,棧的情況如圖3.15(a)所示

mov ax,001ah

mov bx,001bh

push ax

push bx ;ax. bx入棧,棧的情況如圖3.15 (b)所示

sub ax,ax ;將ax清零,也可以用mov ax,0,

;sub ax,ax的機器碼為2個位元組,

;mov ax,。的機器碼為3個位元組。

sub bx,bx

pop bx ;從棧中恢復ax, bx原來的資料,當前棧頂的內容是bx

pop dx ;中原來的內容:oo1bh} ax中原來的內容ooiah在棧頂

;的下面,所以要先pop bx,然後再pop axo

從上面的程式我們看到,用棧來暫存以後需要恢復的暫存器中的內容時,出棧的順序要和入棧的順序相反,因為最**棧的暫存器的內容在棧頂,所以在恢復時,要最先出棧。

問題3.9

程式設計(1)將10000h-1 000fh這段空間當作棧,初始狀態棧是空的:

(2)設定ax=001 ah , bx=001 bh

(3)利用棧,交換ax和bx中的資料。

分析**如下:

mov ax,1000h

mov ss,ax

mov sp,0010h ;初始化棧頂,棧的情況如圖3.16(a)所示

mov ax,001ah

mov bx,001bh

push ax

push bx ;ax. bx入棧,棧的情況如圖3.16 (b)所示

pop ax ;當前棧頂的資料是bx中原來的資料:001bh;

;所以先pop ax, ax=00o1bh;

pop bx ;執行pop ax後,棧頂的資料為ax原來的資料;

;所以再pop bx, bx=00lah;

問題3.10

如果要在10000h處寫入字型資料2266h,可以用以下的**完成:

mov ax,1000h

mov ds,ax

mov ax,2266h

mov [0],ax

補全下面的**,使它能夠完成同樣的功能:在10000h處寫入字型資料2266h

要求:不能使用「mov記憶體單元,暫存器」這類指令。

分析我們來看需補全**的最後兩條指令,將ax中的2266h壓入棧中,也就是說,最終應由push ax將2266h寫入1 0000h處。問題的關鍵就在於:如何使push ax訪問的記憶體單元是1 0000h

push ax是入棧指令,它將在棧頂之上壓入新的資料。是,先將記錄棧頂偏移位址的sp暫存器中的內容減2,使得然後再將暫存器中的資料送入ss:sp指向的新的棧頂單元。

一定要注意:它的執行過程ss:sp指向新的棧頂單元,

所以,要在執行push ax之前,將ss:sp指向10002h(可以設ss=1000h ,sp=0002h),這樣,在執行push ax的時候,cpu先將sp=sp-2,使得ss:sp指向10000h,再將ax中的資料送入ss:sp指向的記憶體單元處,即10000h處

完成的程式如下:

mov ax,1000h

mov ss,ax

mov sp, 2

mov ax,2266h

push ax

從問題3.10的分析中可以看出,push, pop實質上就是一種記憶體傳送指令,可以在暫存器和記憶體之間傳送資料,與mov指令不同的是,push和pop指令訪問的記憶體單元的位址不是在指令中給出的,而是由ss:sp指出的。同時,push和pop指令還要改變sp中的內容。

我們要十分清楚的是,push和pop指令同mov指令不同,cpu執行mov指令只需一步操作,就是傳送,而執行push, pop指令卻需要兩步操作。執行push時,cpu的兩步

操作是:

先改變sp,後向ss:sp處傳送。

執行pop時,cpu的兩步操作是:

先讀取ss:sp處的資料,後改變sp

注意注意,push, pop等棧操作指令,修改的只是sp。也就是說,棧頂的變化範圍最大為:o-ffffh

提供:ss, sp指示棧頂;改變sp後寫記憶體的入棧指令;讀記憶體後改變sp的出棧指令。這就是8086cpu提供的棧操作機制。

棧的綜述

(1)8086cpu提供了棧操作機制,方案如下:

在ss、sp中存放棧頂的段位址和偏移位址

提供入棧和出棧指令,他們根據ss:sp指示的位址,按照棧的方式訪問記憶體單元

(2) push指令的執行步驟

①sp=sp-2;

②向s5:sp指向的字單元中送入資料。

(3)pop指令的執行步駱

①從ss:sp指向的字單元中讀取資料:

②sp=sp+2

(4)任意時刻ss: sp指向棧頂元素。

(5) 8086cpu只記錄棧頂,一棧空間的大小我們要自己管理。

(6)用找來暫存以後需要恢復的暫存器的內容時,暫存器出棧的順序要和入棧的順序相反。

(7)push、pop實質上是一種記憶體傳送指令,注意它們的靈活應用。

彙編自動出棧 8086彙編 棧操作

8086彙編 棧操作 棧結構一 說明 棧是一種只能在一端進行插入或刪除操作的資料結構。棧有兩個基本的操作 入棧和出棧。入棧 將乙個新的元素放到棧頂 出棧 從棧頂取出乙個元素。棧頂的元素總是最 棧,需要出棧時,又最先被從棧中取出。棧的操作規則 lifo last in first out,後進先出 二...

由入棧 出棧序列求所有出棧 入棧序列

給出乙個陣列,代表入棧順序,求所有出棧可能性?給出乙個陣列,代表出棧順序,求所有入棧可能性?這兩題解法相同,可利用全排列求出所有組合,再進行可能性分析。全排列 如下 public list permute int nums 這種方法是什麼意思呢?例如abc,在第0位有三種可能,axx,bxx,cxx...

棧的入棧,出棧,顯示入棧元素

要實現的功能如下 printf t t1.入棧 n printf t t2.出棧 n printf t t3.顯示棧內元素 n define maxsize 5 巨集定義 typedef struct stack 定義棧 void push stack p,int e void printstack...