1. 程式人生 > >組合語言課堂總結3——記憶體訪問

組合語言課堂總結3——記憶體訪問

記憶體中字的儲存

  8086CPU中,用16位暫存器儲存一個字,而在前面的學習中瞭解到記憶體是以位元組為單位劃分的,所以一個字要用兩個地址連續的記憶體單元來存放,這就提出了字資料的存取原則(小端法):高—高,低—低,即,字資料的低位位元組存放在低地址記憶體單元;字資料的高位位元組存放在高地址記憶體單元;取低地址記憶體單元地址作為字資料地址。

ex.

  

  除此之外,還有一種儲存方法叫做大端法,顧名思義,和小端法的儲存方式正好相反。

 

DS[address]  and 字的傳送

  DS,資料段暫存器,通常用來存放要訪問的資料的段地址,在mov, add, sub

等彙編指令中,訪問記憶體單元時,預設情況下,指的是資料段。也就是說,我們可以通過改變DS中的值來訪問指定的記憶體單元,但是8086CPU不允許直接將資料傳入DS暫存器:

   

  所以需要通過一般暫存器來實現過渡,比如:

    MOV BX, 1000H

    MOV DS, BX     DS<-1000H

    MOV AL, [0]

  前兩條mov指令完成了兩種傳送:①將資料直接送入暫存器;②將一個暫存器中的內容送入另一個暫存器。

  “[...]”表示一個記憶體單元,“[...]”中的資料0表示記憶體單元的偏移地址。所以這三條指令實現的功能就是將

10000H ( 1000:0 ) 中的資料讀到AL中。

  所以字的傳送就是使用MOV指令通過16位暫存器在CPU和記憶體之間進行資料的傳送,其中要使用資料段暫存器DS來訪問記憶體單元。

ex.

   

 

MOV、ADD、SUB指令

  MOVADDSUB指令都有兩個操作物件,操作物件可以是常數、暫存器、段暫存器和記憶體單元,但並不是任意兩兩組合都可以使用。

  mov指令:1、兩個運算元長度要一致。

       2常數(立即數)不能作為第1個運算元(目的運算元);作第2個運算元(源運算元)時,如果最高位是十六進位制的afAF,前面要加零。

       3

兩個記憶體單元之間不能直接傳送資料。

       4不能使用mov指令修改CSIP的值。

       5兩個段暫存器之間不能直接傳送;不能把常數送到段暫存器。

   

  add指令:1、運算元不能同時是記憶體單元。

        2、運算元不能是段暫存器。

        3、運算元是記憶體單元時,指令中只給出「偏移地址」。預設,「段地址」在ds中。

   

  sub指令:1兩個記憶體單元不能直接使用sub指令相減。

           2運算元不能是段暫存器。

           3運算元是記憶體單元時,指令中只給出「偏移地址」。預設,「段地址」在ds中。

   

 

  棧是一個邏輯上的概念,可以將一段記憶體空間當作棧來使用。棧有“後進先出”的特性。8086CPU中棧以字為存取單位。

  棧頂是最後入棧的字資料所對應的地址單元;棧底是固定的一端,棧區最高地址單元的前一個單元。8086CPU中有兩個暫存器,SS(棧段段暫存器)和SP(棧指標暫存器),棧頂的段地址存放在SS中,偏移地址存放在SP中,任意時刻,SS:SP指向棧頂元素。

  棧有兩種操作:入棧push和出棧pop

  push:第1步,棧頂上移兩個單元,即:棧頂-2 → 棧頂;第2步,存入資料。

  pop:第1步,取出字資料5020H AX;第2步,棧頂下移兩個單元,即:棧頂+2 → 棧頂。(棧為空時,棧頂指向棧底+2

  pushpop指令形式:

   

  注意:1、在push  記憶體單元和pop 記憶體單元中,指令中只需給出「偏移地址」。預設,段地址在DS中。

     2、8086CPU而言,pushpop的操作:入棧和出棧均以字為單元;操作物件不能是常數;pop 段暫存器中,段暫存器不能是CSSS

        3、利用棧「後入先出」特性,使用pushpop指令可以完成一些特殊處理。

 

棧頂越界問題

  當以下兩種情形出現時會發生棧頂越界問題:

    ·當棧滿的時候,再使用push指令入棧

    ·當棧空的時候,再使用pop指令出棧

  因為每次入棧或出棧改變的都是SP中的值,但是SP的範圍只能在0000~FFFFH之間,也就是說一個棧空間最大隻能有64kb,並且8086CPU不會自動考慮棧頂越界,所以容易發生越界的情況。

  越界情況發生後,也許不會有很大的影響,但也可能會訪問到使用者許可權之外的記憶體,如果隨意操作,可能會導致電腦出現故障;或者是在SPFFFF時繼續執行了pop操作,這時可能會取到我們不需要的垃圾資料。

 

疑問

  在檢測點3.1中有如下三條語句:

    mov ax, 1

    mov ds, ax

    mov ax, [0000]

  為什麼執行完這三條語句後,AX中的值是0000:0010中的值,而不是0001:0000中的值呢?(有沒有哪位大佬可以解答一下我的疑惑哇)