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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

一步步学习汇编系列(7)

發布時間:2024/4/15 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 一步步学习汇编系列(7) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
寄存器(內存訪問)

從訪問內存的角度繼續學習幾個寄存器<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

首先理解幾個要點:

1.內存中字的存儲

n??????? 0地址處開始存放20000

<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" /><?xml:namespace prefix = w ns = "urn:schemas-microsoft-com:office:word" />

?

n??????? 0號單元是低地址單元,1號單元是高地址單元。

備注:任何兩個地址連續的內存單元,N號單元和 N+1號單元,可以將它們看成兩個內存單元 ,也可以看成一個地址為N的字單元中的高位字節單元和低位字節單元。

?

2. DS[address]

n??????? CPU要讀取一個內存單元的時候,必須先給出這個內存單元的地址;

n??????? 8086PC中,內存地址由段地址和偏移地址組成。

n??????? 8086CPU中有一個 DS寄存器,通常用來存放要訪問的數據的段地址。

n??????? ???例如:我們要讀取10000H單元的內容可以用如下程序段進行:

????????? mov bx,1000H

????????? mov ds,bx

????????? mov al,[0]

n??????? 上面三條指令將10000H1000:0)中的數據讀到al中。

mov指令的格式:

????? mov 寄存器名,內存單元地址

“[…]”表示一個內存單元, “[…]”中的0表示內存單元的偏移地址。

那么內存單元的段地址是多少呢?就是上面的ds

?

備注:8086CPU不支持將數據直接送入段寄存器的操作,ds是一個段寄存器。

?(硬件設計的問題)

mov ds,1000H 是非法的。

數據-一般的寄存器-段寄存器

?

明白了以上原理,我們具體來看看字的傳送

3.字的傳送

因為8086CPU16位結構,有16根數據線,所以,可以一次性傳送16位的數據,也就是一次性傳送一個字。

看下面的圖清晰的描述了這個過程:

?

內存中的情況如右圖,寫出下面指令執行后寄存器axbxcx中的值。

分析后就可以知道

Ax=1000h

Ds=1000h

Ax=1123h

Bx=6622h

Cx=2211h

Bx=6622h+2211h=8833hh

Cx=8833hh

?

現在您可以練習一下,看圖寫出每行運行后寄存器的結果,如下:

參考答案提供上來:

?

通過上面的分析,實際上我們已經接觸到了以下幾種指令:

mov 寄存器,數據

? mov 寄存器,寄存器

? mov 寄存器,內存單元

? mov 內存單元,寄存器

? mov 段寄存器,寄存器

?? mov 內存單元,段寄存器

? ?mov 段寄存器,內存單元

?

addsub指令同mov一樣,都有兩個操作對象。

?

4. 數據段

前面講過,對于8086PC機,我們可以根據需要將一組內存單元定義為一個段。

我們可以將一組長度為NN64K)、地址連續、起始地址為16的倍數的內存單元當作專門存儲數據的內存空間,從而定義了一個數據段。

比如我們用123B0H~123B9H這段空間來存放數據:

段地址:123BH

長度:10字節

?? 如何訪問數據段中的數據呢?

將一段內存當作數據段,是我們在編程時的一種安排,我們可以在具體操作的時候 ,用 ds 存放數據段的段地址,再根據需要,用相關指令訪問數據段中的具體單元。

?

例子:

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

5.棧的操作(先進后出)

push 指令的執行過程

先來看入棧的操作,用圖來分析:

?

解釋如下:

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

 ???? 任意時刻,SS:SP指向棧頂,當棧中只有一個元素的時候,SS = 1000HSP=000EH。 

n??????? 棧為空,就相當于棧中唯一的元素出棧,出棧后,SP=SP+2 SP 原來為 000EH,加 2 SP=10H,所以,當棧為空的時候,SS=1000HSP=10H

?

再來看看出棧的操作:

解釋如下:

n??????? 出棧后,SS:SP指向新的棧頂 1000EHpop操作前的棧頂元素,1000CH 處的2266H 依然存在 ,但是,它已不在棧中。

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

?

SSSP只記錄了棧頂的地址,依靠SSSP可以保證在入棧和出棧時找到棧頂。

?

可是,如何能夠保證在入棧、出棧時,棧頂不會超出棧空間。

棧頂超界的問題

看下面的圖:

下面來解釋一下:

n??????? 8086CPU不保證對棧的操作不會超界。

?? 這就是說, 8086CPU 只知道棧頂在何處(由SS:SP指示),而不知道讀者安排的棧空間有多大。這點就好像 CPU 只知道當前要執行的指令在何處(由CS:SP指示)而不知道讀者要執行的指令有多少。

?? 我們在編程的時候要自己操心棧頂超界的問題 ,要根據可能用到的最大棧空間,來安排棧的大小,防止入棧的數據太多而導致的超界;執行出棧操作的時候也要注意,以防棧空的時候繼續出棧而導致的超界。

看下面棧頂超出棧空間的情況:

?

解釋如下:

? 1/當棧空時,此時ss=1000h,sp=0020h;

當執行了八次壓棧后,棧滿了,此時ss=1000h,sp=0010h;

如果再執行一次,那么此時ss=1000h,sp=sp-2=000e,這樣就把其它內存地址給復蓋了,這對程序來講是致命 的。

?

出棧的原理和入棧原理類似,在此就不用圖描述了。讀者可自己去體會。



總結如下:
?

n

n??????? 我們可以將一段內存定義為一個段,用一個段地址指示段,用偏移地址訪問段內的單元。這完全是我們自己的安排。

n??????? 我們可以用一個段存放數據,將它定義為數據段

n??????? 我們可以用一個段存放代碼,將它定義為代碼段

n??????? 我們可以用一個段當作棧,將它定義為棧段

?

n??????? 我們可以這樣安排,但若要讓CPU按照我們的安排來訪問這些段,就要:

n??????? 對于數據段,將它的段地址放在 DS中,用movaddsub等訪問內存單元的指令時,CPU就將我們定義的數據段中的內容當作數據段來訪問;

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

n??????? 對于棧段,將它的段地址放在SS中,將棧頂單元的偏移地置放在 SP 中,這樣CPU在需要進行棧操作的時候,比如執行 pushpop 指令等,就將我們定義的棧段當作棧空間來用

?????

可見,不管我們如何安排 CPU 將內存中的某段內存當作代碼 ,是因為CS:IP指向了那里;CPU將某段內存當作棧 ,是因為 SS:IP 指向了那里。

?

?

?

?

?

?

?

?

?

?

轉載于:https://www.cnblogs.com/mfm11111/archive/2009/03/26/1422648.html

總結

以上是生活随笔為你收集整理的一步步学习汇编系列(7)的全部內容,希望文章能夠幫你解決所遇到的問題。

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