前面的部落格都多少提到了8086彙編的記憶體定址,例如mov ax [2345h]。而8086彙編還提供了更多、更靈活的定址方式,以滿足多種需求。
需要強調的是,無論何種定址方式,記憶體定址的位址總是由基礎位址+偏移位址(段基址+偏移量)組合而成,不同之處在於基礎位址與偏移位址應該從何處獲得。
在示例mov ax [2345h]中,並沒有顯示的指明段位址的值,這是因為8086彙編在處理沒有明確指明段基址的指令時,一般預設將資料段暫存器ds的值作為段基址。也就是說,mov ax [2345h]其實是mov ax ds:[2345h]的縮寫。
特別的,當偏移位址的指定,存在了bp段暫存器時,則預設的段暫存器為ss棧段暫存器,指令mov ax [bp]實際為mov ax ss:[bp]的縮寫形式。
8086彙編中通過「段暫存器:偏移位址」的方式指定定址時的段基址。而ds並不是唯一的段暫存器,在記憶體定址時的段位址可以不存放於段暫存器ds中,而是存放其它的段暫存器中。可以在指令中顯式的指明(mov ax cs:[2345h] 此時的段位址在**段暫存器cs中)。
8086彙編提供偏移位址的方式很多樣,大致可以分為五類:直接定址、暫存器間接定址、暫存器相對定址、基址變址定址、相對基址變址定址,按照先後順序,靈活性和複雜度逐漸增加。
偏移位址可能由某一暫存器指定,也可能存放在某一處記憶體中,或是在指令緩衝器中,亦或是由它們的組合構成。
直接定址
直接定址其實就是前面提到過的定址方式(mov ax [2345h]),其所指明的定址偏移位址直接儲存在指令中,在實際執行時,cpu會從指令緩衝器中獲取到對應的偏移值進行記憶體定址。
這裡提出乙個idata(immediate data)直接數、立即數的概念,用以指代1000h或是2345h這樣指令中的常量值。包含idata常量的指令,其值都存放在指令緩衝器中,供cpu在執行時獲取。
指令mov ax, 1000h,代表將立即數1000h送入ax中,可以抽象表示為mov ax, idata的形式。
指令mov ax, [1000h],代表對ds:1000h記憶體進行定址,可以抽象表示為mov ax, [idata]的形式。
暫存器間接定址
暫存器間接定址,從定址方式的名字中可得,位址不是常量而是類似乙個變數,其值存在於一類特殊的暫存器,尋值暫存器中。
需要注意的是,8086並不允許所有的暫存器作為暫存器間接定址之用,而只有暫存器bx、bp、si、di這四個暫存器被稱為尋值暫存器,可用於暫存器間接定址。暫存器間接定址時使用其它的暫存器都會被編譯器認為是語法錯誤。
暫存器間接定址的的方式為[bx]/[bp]/[si]/[di]四種,例如mov ax,[bx],指令的含義為將記憶體位址為ds:bx處的資料送入暫存器ax中。
暫存器相對定址
通過常量idata或是特定型別暫存器可以指定偏移位址進行定址,直接定址和暫存器間接定址只選用了暫存器或立即數idata中的一種元素,較為簡單。而更複雜的定址方式是將常量idata和暫存器定址組合起來實現的。
暫存器相對定址是通過將定址暫存器與idata結合起來進行的。 在暫存器相對定址這種乙個定址暫存器+乙個常量的定址模式中,bx/bp/si/di是等價的。
暫存器相對定址較為靈活,大致有以下幾種(第1種是標準格式,2、3、4是語法糖):
1.[bx+idata]/[bp+idata]/[si+idata]/[di+idata] 標準格式
2.[bx].idata/[bp].idata/[si].idata/[di].idata 一般用於結構體
3.idata[bx]/idata[bp]/idata[si]/idata[di] 一般用於一維陣列
4.[bx][idata]/[bp][idata]/[si][idata]/[di][idata]一般用於二維陣列
為什麼8086彙編會為暫存器相對定址提供如此之多語法不同但本質一樣的語法糖呢?仔細觀察可以發現,2、3、4的寫法很像高階語言中的結構體/物件、陣列的訪問方式。8086提供的多樣的語法格式能夠讓寫出的程式更加易於理解。後續的部落格會對8086彙編模擬高階語言中陣列、結構體的記憶體結構設計進行詳細說明。
基址變址定址
基址變址定址比暫存器相對定址的方式更加靈活,是通過兩個不同的定址暫存器組合而成。但這裡bx/bp/si/di並不能隨意的兩兩搭配,其中bx/bp一組,si/di一組。不同組之間的定址暫存器才能兩兩組合,共有四種:[bx+si]、[bx+di]、[bp+si]、[bp+di]。
基址變址定址一般用於對二維陣列中資料的定址。
相對基址變址定址
相對基址變址定址在基址變址定址的基礎上,再新增了乙個idata常量元素,定址模式是兩個變數+乙個常量,是最複雜也最靈活的一種定址方式。
和基址變址定址定址類似,相對基址變址定址也有四種方式:[bx+si+idata]、[bx+si+idata]、[bx+si+idata]、[bx+si+idata]。
8086cpu提供的相對基址變址定址方式,為處理巢狀的結構化資料提供了方便,如訪問結構體中的陣列時可以比較自然的表達其偏移位址。
8086組合語言
cmc 進製位求反指令 stc 進製位置為1指令 cld 方向標誌置1指令 std 方向標誌位置1指令 cli 中斷標誌置0指令 sti 中斷標誌置1指令 nop 無操作 hlt 停機 wait 等待 esc 換碼 lock 封鎖 附上 藍色理想 的彙編學習心得位址 從今天開始溫習彙編了 1 基本概...
8086組合語言學習 九 8086標誌暫存器
前面已經介紹了8086大多數的暫存器,現在介紹一種8086內部乙個特殊的暫存器,標誌暫存器 flag register 8086標誌暫存器大致有以下作用 1.儲存一些相關指令的執行結果 2.為cpu執行相關指令提供依據 3.控制cpu的部分工作方式 8086的暫存器是16位的,通常的暫存器都是存放乙...
8086組合語言學習 三 8086中的段和棧
8086對記憶體定址的方式是通過段位址 16 偏移位址的方式實現的,而在16位的8086cpu下,段位址和偏移位址也都是16位的。這意味著,對於任意乙個段,段的起始位址必定為16的倍數 段位址 16 需要注意,記憶體段的概念並不是記憶體硬體所固有的,而是從cpu定址的角度出發,將記憶體中的物理連續區...