小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

匯編語言——寄存器

 yidiantou 2018-11-16

一、棧的基本概念

棧有兩個(gè)基本的操作:入棧和出棧。
入棧:將一個(gè)新的元素放到棧頂;
出棧:從棧頂取出一個(gè)元素。
棧頂?shù)脑乜偸亲詈笕霔?,需要出棧時(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)作棧來使用(其實(shí)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ù)?個(gè)內(nèi)存單元取出放到AX寄存器中,AX=1122H           
 pop bx          # 將棧頂?shù)?個(gè)內(nèi)存單元取出放到BX寄存器中,BX=2266H
 pop cx          # 將棧頂?shù)?個(gè)內(nèi)存單元取出放到CX寄存器中,CX=0123H

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

8086CPU中,有兩個(gè)寄存器:

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

任意時(shí)刻,SS:SP指向棧頂元素。

二、push和pop指令

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

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

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

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

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

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

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

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

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

解決辦法:一個(gè)很NC的辦法,就是我們?cè)诰幊痰臅r(shí)候要自己操心棧頂超界的問題 ,要根據(jù)可能用到的最大??臻g,來安排棧的大小,防止入棧的數(shù)據(jù)太多而導(dǎo)致的超界;執(zhí)行出棧操作的時(shí)候也要注意,以防??盏臅r(shí)候繼續(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操作的時(shí)候回將sp-2,所以我們要把它指向10002H的位置
mov ax,2266H
push ax

棧段

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

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

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

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

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

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

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

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多