免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
匯編語言——寄存器

一、棧的基本概念

棧有兩個基本的操作:入棧和出棧。
入棧:將一個新的元素放到棧頂;
出棧:從棧頂取出一個元素。
棧頂?shù)脑乜偸亲詈笕霔?,需要出棧時,又最先被從棧中取出。
棧的操作規(guī)則:后進(jìn)先出

8086CPU提供的棧機(jī)制

8086CPU提供入棧和出棧指令: (最基本的)
PUSH(入棧)
POP (出棧)
push ax:將寄存器ax中的數(shù)據(jù)送入棧中;
pop ax :從棧頂取出數(shù)據(jù)送入ax。

push和pop指令也可以在內(nèi)存和寄存器傳輸數(shù)據(jù)(以棧的形式)
8086CPU的入棧和出棧操作都是以為單位進(jìn)行的。

示例:

1
2
3
4
5
6
7
8
9
10
11
假設(shè)將10000H~1000FH這段內(nèi)存當(dāng)作棧來使用(其實CPU并不知道這段是代碼段,數(shù)據(jù)段還是棧段,都是人為設(shè)定的)
下面一段指令的執(zhí)行過程:
 mov ax,0123H    # AX=0123H
 push ax         # 將AX的值推入棧中
 mov bx,2266H    # BX=2266H
 push bx         # 將BX的值推入棧中
 mov cx,1122H    # CX=1122H
 push cx         # 將CX的值推入棧中
 pop ax          # 將棧頂?shù)?個內(nèi)存單元取出放到AX寄存器中,AX=1122H           
 pop bx          # 將棧頂?shù)?個內(nèi)存單元取出放到BX寄存器中,BX=2266H
 pop cx          # 將棧頂?shù)?個內(nèi)存單元取出放到CX寄存器中,CX=0123H

那么問題來了,在執(zhí)行push和pop的時候,如何知道哪個單元是棧頂單元?

8086CPU中,有兩個寄存器:

  • 段寄存器SS  存放棧頂?shù)亩蔚刂?/strong>
  • 寄存器SP  存放棧頂?shù)钠频刂?/strong>

任意時刻,SS:SP指向棧頂元素。

二、push和pop指令

push 指令的執(zhí)行過程

在執(zhí)行push ax指令時,主要做了一下2件事
(1)先將SP=SP–2
(2)將ax中的內(nèi)容送入SS:SP指向的內(nèi)存單元處,SS:SP此時指向新棧頂。

pop 指令的執(zhí)行過程

在執(zhí)行pop ax指令時,主要做了一下2件事
(1)先將SS:SP指向的內(nèi)存單元處的數(shù)據(jù)送入ax中;
(2)SP = SP+2,SS:SP指向當(dāng)前棧頂下面的單元,以當(dāng)前棧頂下面的單元為新的棧頂。

當(dāng)棧為空的時候,SS:SP指向最高地址空間的下一位

任意時刻,SS:SP 指向棧頂元素,當(dāng)棧為空的時候,棧中沒有元素,也就不存在棧頂元素,所以SS:SP 只能指向棧的最底部單元下面的單元,該單元的偏移地址為棧最底部的字單元的偏移地址+2,棧最底部字單元的地址為1000:000E,所以??諘r,SP=0010H。

棧頂超界的問題(簡單了解就好,我們又不做黑客)

原因:SS和SP只記錄了棧頂?shù)牡刂罚?strong>依靠SS和SP可以保證在入棧和出棧時找到棧頂。

上面我說了,CPU并不知道這段是代碼段,數(shù)據(jù)段還是棧段,都是人為設(shè)定的所以加入這個??樟耍覀兝^續(xù)pop,它就會把其它段的數(shù)據(jù)pop出。所以非常危險

解決辦法:一個很NC的辦法,就是我們在編程的時候要自己操心棧頂超界的問題 ,要根據(jù)可能用到的最大棧空間,來安排棧的大小,防止入棧的數(shù)據(jù)太多而導(dǎo)致的超界;執(zhí)行出棧操作的時候也要注意,以防棧空的時候繼續(xù)出棧而導(dǎo)致的超界。

push和pop指令具體可以操作

1
2
3
4
5
6
7
8
9
10
11
# 可以為通用寄存器賦值
push ax
pop bx
# 可以為段寄存器賦值
push ds
pop es
# 可以為內(nèi)存單元賦值
push [0]
pop [2]

示例:

1、將10000H~1000FH 這段空間當(dāng)作棧,初始狀態(tài)是空的,將 AX、BX、DS中的數(shù)據(jù)入棧。

2、編程

(1)將10000H~1000FH 這段空間當(dāng)作棧,初始狀態(tài)是空的;
(2)設(shè)置AX=001AH,BX=001BH;
(3)將AX、BX中的數(shù)據(jù)入棧;
(4)然后將AX、BX清零;
(5)從棧中恢復(fù)AX、BX原來的內(nèi)容。

3、編程:

(1)將10000H~1000FH 這段空間當(dāng)作棧,初始狀態(tài)是空的;
(2)設(shè)置AX=002AH,BX=002BH;
(3)利用棧 ,交換 AX 和 BX 中的數(shù)據(jù)。

 

4、補(bǔ)全下面的代碼,完成同樣的功能:在10000H處寫入字型數(shù)據(jù)2266H。

__________
__________
__________
mov ax,2266H
push ax

1
2
3
4
5
mov ax,1000H
mov ss,ax
mov sp,2    # 題目要求的是要將10000H位置寫入字形數(shù)據(jù),10000H的偏移量是0,在執(zhí)行push操作的時候回將sp-2,所以我們要把它指向10002H的位置
mov ax,2266H
push ax

棧段

上面說過我們可以定義一段內(nèi)存單元為代碼段,數(shù)據(jù)段或棧段。

我們可以將一個段空間當(dāng)做一個棧段,一個棧段最大64K,因為16位CPU的偏移地址最大為2^16B,如果超出FFFF它會重新變成0(FFFF+1=0000,1被拋棄了)。

CPU是如何判斷哪塊是什么段的?

我們可以將一段內(nèi)存定義為一個段,用一個段地址指示段,用偏移地址訪問段內(nèi)的單元。這完全是我們自己的安排。
我們可以用一個段存放數(shù)據(jù),將它定義為“數(shù)據(jù)段”;
我們可以用一個段存放代碼,將它定義為“代碼段”;
我們可以用一個段當(dāng)作棧,將它定義為“棧段”;
我們可以這樣安排,但若要讓CPU按照我們的安排來訪問這些段,就要:
對于數(shù)據(jù)段將它的段地址放在 DS中,用mov、add、sub等訪問內(nèi)存單元的指令時,CPU就將我們定義的數(shù)據(jù)段中的內(nèi)容當(dāng)作數(shù)據(jù)段來訪問;

對于代碼段,將它的段地址放在 CS中,將段中第一條指令的偏移地址放在IP中,這樣CPU就將執(zhí)行我們定義的代碼段中的指令;

對于棧段,將它的段地址放在SS中,將棧頂單元的偏移地置放在 SP 中,這樣CPU在需要進(jìn)行棧操作的時候,比如執(zhí)行 push、pop 指令等,就將我們定義的棧段當(dāng)作棧空間來用。

可見,不管我們?nèi)绾伟才?,CPU 將內(nèi)存中的某段內(nèi)存當(dāng)作代碼 ,是因為CS:IP指向了那里;CPU將某段內(nèi)存當(dāng)作棧 ,是因為 SS:IP 指向了那里。

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服