今天我們來解決這樣乙個問題,利用棧的的特性,將**段中定義的資料進行逆序存放。請看下面**段:
assume cs:code
code segment
dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
;?code ends
end start
預備知識
對**段使用資料是dw(define word) 程式會向記憶體申請乙個字單元也就是2個位元組。
如何將一段連續的記憶體空間設定為乙個棧段?使用ss、sp 暫存器,ss 代表棧段的段位址,sp代表偏移位址,注意彈棧 壓棧 sp 都移動的2個位元組。
壓棧彈棧問題?彈棧是 向將資料彈出,再進行的sp = sp +2,壓棧是 先將 sp = sp-2 後在壓資料 ,為啥呢?是因為彈棧 壓棧都是根據偏移量sp進行push和pop的!
你仔細領悟領悟。所以在壓棧前我們的 sp 要指向 空閒單元的位址高1個位元組的記憶體單元,這一點很重要。如果你理解了,就知道為啥 c/c++中有這樣乙個說法,棧的生長是從高位址到低位址了。
可以通過段暫存器:偏移量對記憶體單元進行訪問
迴圈語法loop的使用。
assume cs:code
code segment
dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
dw 0,0,0,0, 0,0,0,0
start:
;設定 棧段
mov ax,cs
mov ss,ax
mov sp,20h
mov bx,0
;設定 迴圈次數
mov cx,8
;先壓棧
s:push cs:[bx]
add bx,2
loop s
mov bx,0
mov cx,8
;後彈棧
s1:pop cs:[bx]
add bx,2
loop s1
mov ax,4c00h
int 21h
code ends
end start
在組合語言 王爽 書中的原**中,定義的是 16字單元,sp 是設定的 30h,猜想作者是申請更多空間,反正沒壞處。其實本人認為定義8個字單元足夠,我們需要逆置的資料也才8個字單元,如果申請8個字單元,那麼sp的設定就要當心了,是空閒單元的最高位址+1,先移動到空閒單元然後開始壓棧!位址最高的空閒單元是sp = 19h ,所以 mov sp,20h 沒毛病,網上有說mov sp,21h 這是錯的。壓棧前sp指向**段第一條指令,sp 先-2 然後壓入1個字資料!
第一步檢視記憶體單元資料。
第二步**執行到第乙個迴圈(壓棧)結束,檢視是否將記憶體單元的數值全部壓棧到空閒單元。
第三步**執行到第二個迴圈(彈棧)結束,檢視記憶體單元數值是否逆置。
關於組合語言棧的理解
棧就是一段特殊記憶體,什麼是棧呢?舉個例子,乙個只有上面開啟的盒子,現在有三本書離散數學 c語言 組合語言,需要將這三本書一本一本的放進去,先將離散數學放進去,然後c語言,接著組合語言,現在又需要將三本書拿出去,只能先拿組合語言,再拿c語言接著再拿離散數學,棧就是這樣的特點,後進先出。棧的大小怎麼確...
組合語言 記憶體變數的位址
計算機中的記憶體是以位元組為單位的連續的儲存空間,每個位元組都有乙個唯一的編號,這個編號就稱為記憶體位址 因為記憶體的儲存空間是連續的,所以,記憶體位元組的位址編號也是連續的,並用二進位制或十六進製制數來表示 在記憶體中,每個變數都有自己的儲存單元,不同型別的變數占用的儲存單元空間大小不一樣 對於多...
組合語言的資料表示
組合語言程式設計師處理的是物理級資料,因此他們必須善於檢查記憶體和暫存器。通常,二進位制數被用於描述計算機記憶體的內容 有時也使用十進位制和十六進製制數。所以必須熟練掌握數字格式,以便快速地進行數字的格式轉換。每一種數制格式或系統,都有乙個基數 base 也就是可以分配給單一數字的最大符號數。下表給...