彙編語言學習筆記二:訪問內存的寄存器

1、通過前一篇章的學習,知道CS和IP寄存器的內容合成的物理地址指向的是執行指令的地址。而訪問內存也需要知道內存的地址,內存地址也是由段地址和偏移地址組成,8086CPU中默認存放內存地址段地址的寄存器是DS寄存器,偏移地址則是由[n]表示,n表示偏移量。例子:

MOVBX,1000H   //將1000H存放到BX寄存器當中

MOVDS,BX      //將BX中的值(1000H)存放到段寄存器DS中

MOVAL,[0]     //注意這裏,既然是AL,那麼移動是以字節爲單位,

              //因爲AL爲AX的低位,長度爲8位。[0]表示內存

              //偏移地址是0H,默認段地址爲DS中的值1000H,

              //整體意思是將10000H中的數據存放在AL中。

(1)要注意,數據和段寄存器直接是不能直接傳遞的,因此必須以普通寄存器爲中介,現將數據存入通用寄存器,再將通用寄存器的數據傳入段寄存器中。

(2)假如第三條指令是MOV AX,[0],那麼就是傳遞一個字的內容,就是將10000H和10001H中的數據總計16位存入寄存器AX當中。

2、內存單元(以字節爲單位)存儲數據時,是以字節爲單位存放,存放的形式與系統是大端還是小端有關。小端是低地址存放低位字節,高地址存放高位字節;大端則是低地址存放高位字節,高地址存放低位字節。這裏講的8086是小端系統。8086的寄存器是16位。那麼一次性可以存放一個字(兩個字節)。而存放一個字是用兩個地址連續的內存單元來存放,由低地址到高地址,分別存放字的低位到高位。

3、MOV指令除了不能將數據直接存入段寄存器之外,寄存器和寄存器、段寄存器和寄存器、內存單元和寄存器、內存單元和段寄存器之間都可以傳遞數據(反過來也可以)。

4、棧有兩個基本的操作:入棧和出棧。都只和棧頂有關,入棧就是將新的數據放到棧頂,出棧就是從棧頂取出一個元素,那麼棧的這種操作就是LIFO(後進先出)。CPU也提供棧機制,並且有兩個相關的指令PUSH和POP。PUSH表示入棧,POP表示出棧。CPU的入棧出棧操作都是以字(非字節)爲單位。具體執行過程可以見下圖:


(1)圖1表示初始狀態棧頂地址爲10010H,由圖1到圖4得知,當需要入棧時,先將棧頂地址減去2個字節(以字爲單位),得到1000EH,然後在1000EH存放數據的低位(低地址低位),1000FH存放數據的高位(高地址高位),此時棧頂地址爲1000EH。由此可知,棧頂地址存放有數據,要想PUSH,必須先讓棧頂地址減2,再存放數據。(先減地址存放數據)

(2)而圖5到圖7可以直到,出棧操作與入棧操作相反,先將棧頂數據出棧,然後再讓棧頂地址加上2個字節。(先取數據再加地址)

(3)由此可知,棧數據增加的過程是地址由高到低的過程。

5、CS和IP合成的地址內是需要執行的指令,DS和[n]合成的地址內是內存訪問的地址。那麼棧頂地址的段地址和偏移地址存放在哪呢?答案是SS段寄存器和SP寄存器。任意時候,SS:SP都指向棧頂地址(入棧的時候,記得現將棧頂地址減2)。

6、棧的空間大小應當有個範圍,那麼入棧和出棧就會有越界的風險,然而8086CPU並沒有相應的措施阻止越界操作。棧空間之外存放的是數據、代碼。假如越界而將數據、代碼意外的改寫,將會引起一連串的錯誤,所以程序員自身要儘量避免越界。

7、push和pop操作可以對寄存器、段寄存器、內存單元使用。



發佈了35 篇原創文章 · 獲贊 1 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章