日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

汇编语言之寄存器(内存访问)

發布時間:2023/12/4 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 汇编语言之寄存器(内存访问) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1、內存中字的存儲

2、ds和【address】

CPU要讀寫一個內存單元的時候,必須先給出這個內存單元的地址,在8086CPU中,內存地址由段地址和偏移地址組成,

其中,段地址存放在段寄存器DS中,DS稱作數據段寄存器。

如果我們要將內存地址為14A70的內存單元中的數據送入AL中,可以用如下的程序段進行:

Mov bx,1000H??? ;把段地址1000H送入bx中。

mov ds,bx??????? ;把bx中的數值送入ds中。

Mov al,[4a70]???? ;把段地址為1000H,偏移地址位4a70H的內存單元中的數據送入al中。

[address]表示一個內存單元,內存單元中的address表示偏移地址,它的中文翻譯就是地址的意思。

內存單元[address],我們可以知道它的地址是多少,但它的數值是多少,我們并不知道。

3、mov指令

傳送指令mov可以完成以下4種傳送:

1:將數據直接送入寄存器。??? 如:mov ax,1230H。

2:將一個寄存器中的數據送入另一個寄存器。??? 如:mov ax,bx

3:將一個內存單元中的數據送入一個寄存器。??? 如:mov ax,[27b0]

4:將一個寄存器中的數據送入內存單元中。??? 如:mov [607c],bx

注意:不能直接用數據送給段寄存器,如:mov ds,1230H 是錯誤的,必須要用一個寄存器來進行中轉。比如:

Mov bx,1230H

Mov ds,bx

這樣就行了。為什么8086CPU不支持將數據直接送入段寄存器呢?這屬于8086CPU硬件設計的問題,我們只要知道這一

點就行了。

4、add和sub指令

Mov指令有兩個操作對象,add和sub同樣有兩個操作對象。

Add為加法指令,格式:add 操作對象1,操作對象2。功能:兩數相加,并把結果保存到操作對象1中。

Add有以下幾種形式:

Add 寄存器,數據??? 如:add ax, 8

Add 寄存器,寄存器??? 如:add ax, bx

Add 寄存器,內存單元??? 如:add ax, [27a0]

Add 內存單元,寄存器??? 如:add [46e9], bx

?

Sub為減法指令,格式:sub 操作對象1,操作對象2。功能:兩數相減,即從操作對象1減去操作對象2,其結果保存到

操作對象1中。

Sub 也有以下幾種形式:

Sub 寄存器,數據??? 如:sub ax, 9

Sub 寄存器,寄存器??? 如:sub ax, bx

Sub 寄存器,內存單元??? 如:sub ax, [b027]

Sub 內存單元,寄存器??? 如:sub [8601], bx

5、數據段

前面講過(參見2.7節),對于8086PC機,在編程時,可以根據需要,將一組內存單元定義為一個段。我們可以將一組長度

為N(N≤64KB)、地址連續、起始地址為16的倍數的內存單元當作專門存儲數據的內存空間,從而定義了一個數據段。

比如:用123B0H~123B9H這段內存空間來存放數據,我們就可以認為123B0H~123B9H這段內存是一個數據段,長度

為10個字節。

如何訪問數據段中的數據呢?首先用DS存放數據段的段地址,然后用相關的指令訪問數據段中的內存單元。

比如,將123B0H~123B9H的內存單元定義為數據段,現在要累加這個數據段中的前3個單元中的數據,代碼如下:

Mov ax, 123BH

Mov ds, ax??? ;將123BH送入ds中,作為數據段的段地址。

Mov al, 0????? ;用al存放累加結果,先把al中的數據清零。

Add al, [0]???? ;將數據段第一個單元(偏移地址為0)中的數值加到al中。

Add al, [1]???? ;將數據段第二個單元(偏移地址為1)中的數據加到al中。

Add al, [2]???? ;將數據段第三個單元(偏移地址為2)中的數據加到al中。

?

在1.5節中,我們說過,在內存中指令和數據沒有任何區別,都是二進制信息,CPU在工作的時候,把有的信息看作指令,

把有的信息看作數據,那么CPU在什么時候把它看作指令?在什么時候把它看作數據呢?在2.5節中我們回答了第一個問題,現

在可以回答第二個問題了。

答:只要把這一段內存單元的段地址放到DS中,在用mov、add、sub等訪問內存單元的指令時,CPU就會將這些內存單

元看作數據來訪問。

6、棧

棧是一種具有特殊的訪問方式的存儲空間,它的特殊性就在于:最后進入這個空間的數據最先出去。可以用一個盒子和3本書

來描述棧的這種操作方式。

入棧:把A放入棧中,再把B放入棧中,然后再把C放入棧中。就形成了A、B、C

出棧:先出棧頂C,然后是B,然后A,

特點:先進后出

入棧和出棧。入棧就是將一個新的元素放到棧頂,出棧就是從棧

頂取出一個元素。棧頂的元素總是最后入棧,需要出棧時又最先被從棧中取出,棧的這種操作規則被稱為LIFO(last in first out,

后進先出)

?

7、cpu提供的棧機制?

現今的CPU中都有棧的設計。8086CPU提供的入棧和出棧指令,最基本的兩個是push(入棧)和pop(出棧)。比如:

Push ax 表示將寄存器ax中的數據送入棧中,pop ax 表示從棧頂取出數據送入ax。8086CPU的入棧和出棧操作都是以字為

單位進行的。

下面兩張圖描述了push和pop指令的執行過程。

上面兩張圖指令的執行過程,寫成代碼如下:

Mov ax, 123H

Push ax

Mov bx, 2266H

Push bx

Mov cx, 1122H

Push cx

Pop ax

Pop bx

Pop cx

注意:字型數據用兩個內存單元存放,高地址單元存放高8位,低地址單元存放低8位。

看了上面兩張圖后,現在提出兩個問題。問題1:我們將10000H~1000FH這段內存當作棧來使用,CPU是如何知道這段空

間是棧?關于這個問題將在3.10節解答。

問題2:push ax等入棧指令執行時,要將寄存器中的數據放入當前棧頂單元的上方,成為新的棧頂元素;pop ax等指令執

行時,要從棧頂單元取出數據送入寄存器中。顯然,push、pop在執行的時候,CPU必須要知道哪個單元是棧頂單元,可是,如

何知道?

答:8086CPU中,有兩個寄存器,堆棧段寄存器SS,堆棧指針寄存器SP,棧頂的段地址存放在SS中,偏移地址存放在

SP中,任意時刻,SS:SP指向棧頂元素,push和pop指令在執行時,CPU從SS和SP中得到棧頂單元的地址。

現在,我們可以完整地描述push和pop指令的功能了,例如:push ax。push ax的執行,由以下兩步完成:

1. SP=SP-2,SS:SP指向當前棧頂前面的單元,以當前棧頂前面的單元為新的棧頂。

2. 將ax中的數據送入SS:SP指向的內存單元處,SS:SP此時指向新棧頂。

下圖描述了push ax的執行過程。

將10000H~1000FH這段空間當作棧段,SS=1000H,棧空間大小為16字節,棧最底部的字單元地址為1000:000E,任

意時刻,SS:SP指向棧頂,當棧中只有一個元素的時候,SS=1000H,SP=000EH,棧為空,就相當于棧中唯一的元素出棧后,

SP=SP+2,原來為000EH,加2后SP=0010H,所以,當棧為空的時候,SS=1000H,SP=0010H。

換一個角度看,任意時刻,SS:SP指向棧頂元素,當棧為空的時候棧中沒有元素,也就不存在棧頂元素,所以SS:SP只能指

向棧的最底部單元下面的單元,該單元的偏移地址為棧最底部的字單元的偏移地址+2,棧最底部字單元的地址為1000:000E,

所以,棧空時,SP=0010H。

接下來,我們描述pop指令的功能,例如:pop ax。Pop ax的執行過程和push ax剛好相反,由以下兩步完成:

1. 將SS:SP指向的內存單元處的數據送入ax中。

2. SP=SP+2,SS:SP指向當前棧頂下面的單元,以當前棧頂下面的單元為新的棧頂。

下圖描述了pop ax的執行過程。

注意:上圖中,出棧后,SS:SP指向新的棧頂1000EH,pop操作前的棧頂元素,1000CH處的數據2266H依然存在,但

是,它已不在棧中,當再次執行push等入棧指令后,SS:SP移至1000CH,并在里面寫入新的數據,將它覆蓋。

8、push指令 pop指令

Push和pop指令的格式有如下兩種形式:

第一種形式:push 寄存器??? ;將一個寄存器中的數據入棧。

??????????? Pop 寄存器??? ;出棧,用一個寄存器接收出棧的數據。

這一種形式,它們可以在棧和寄存器之間傳送數據。

注意:上面的寄存器可以是段寄存器,比如,可以是:push ds、pop ds。

第二種形式:push 內存單元??? ;將一個內存單元中的字型數據入棧(注意,棧操作都是以字為單位)。

??????????? Pop 內存單元??? ;出棧,用一個內存字單元接收出棧的數據。

比如:mov ax, 1000H

????? Mov ds, ax??? ;將內存單元的段地址放在DS中。

????? Push [2a38]??? ;將內存單元[2a38]中的字型數據入棧。

????? Pop [2a3a]??? ;出棧,出棧的數據送入內存單元[2a3a]。

這一種形式,它們可以在棧和內存單元之間傳送數據。

指令執行時,CPU要知道內存單元的地址,可以在push、pop指令中給出內存單元的偏移地址,段地址在指令執行時,CPU

從DS中取得。

Push和pop實質上是一種內存傳送指令,與mov指令不同的是,push和pop指令訪問的棧空間的地址不是在指令中給出

的,而是由SS:SP指出的。同時,push和pop指令還要改變SP中數值。Mov指令只需一步操作,就是傳送,而執行push、

Pop指令需要兩步操作,執行push時,先改變SP,后向SS:SP處傳送;執行pop時,先讀取SS:SP處的數據,后改變SP。

9 、 棧段

前面講過(參見2.7節),對于8086PC機,在編程時,可以根據需要,將一組內存單元定義為一個段。我們可以將長度為N

(N≤64KB)的一組地址連續、起始地址為16的倍數的內存單元,當作棧空間來用,從而定義了一個棧段。

比如,我們將10010H~1001FH這段內存空間當作棧來用,以棧的方式進行訪問,這段空間就可以認為是一個棧段,大小為

16個字節。

如何使得如push、pop等棧操作指令訪問我們定義的棧段呢?那就是要將SS:SP指向我們定義的棧段。

現在我們來回答3.8節中的第一個問題。答:只要這段內存單元被SS:SP指向,那么,CPU就會把這段空間當作棧來使用。



總結

以上是生活随笔為你收集整理的汇编语言之寄存器(内存访问)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。