前面我們一直在使用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...