【x86彙編】第二章:尋址方式

尋址方式

定義:尋找操作數存放地址的方式
在進行一個操作之前,需要知道源操作數和目的操作數分別存放在什麼位置,用什麼方式去找到這個位置

操作數的位置

  • CPU寄存器
  • 主存(內存)
  • IO設備

寄存器尋址

示例:INC AX

操作數存放在CPU寄存器內,寄存器的名字就是它的地址,直接操作對應的寄存器

  • 操作數的類型:由所用寄存器的位數決定,如AX是16位字類型

寄存器間接尋址

示例:MOV AX, [SI]

操作數存放在內存中,需要通過寄存器的值(該值就是操作數的偏移地址EA)間接找到操作數

  • 操作數的類型:不明確,對於雙操作數的指令,如例子所示,由於AX類型已知,則另一個操作數默認使用同樣類型,如果兩個操作數類型都不明確,則出錯
  • 寄存器的選擇:
    • 可以是32位的8個通用寄存器
    • 也可以是4個16位通用寄存器(BX,DI,SI,BP)
    • 但是不能是8位寄存器,需要注意的是被允許的16位寄存器只有這四個
  • 操作數的段:如果寄存器選用ESP、SP、BP,則默認在堆棧段SS,否則一律默認在數據段DS

變址尋址

示例:MOV AL, 5[EBX]

操作數存放在內存中,需要根據寄存器的值、比例因子、位移量,計算出操作數的偏移地址EA,然後去所在段找到操作數,注意選用ESP時,比例因子F只能爲1

  • 書寫形式:常見以下三種,其中R是寄存器,F是比例因子,V是位移量
    1.[R * F + V]
    2.[R * F] + V
    3.V [R * F]
  • 寄存器選擇,操作數的段,同間接尋址的規定一樣

基址加變址尋址

示例:MOV AX, 8[BX][SI]

操作數在內存中,先計算EA,再在段中找到操作數

  • 書寫格式:常見的以下三種,BR是基址寄存器,IR是變址寄存器,F是比例因子,V是位移量
    1.[BR + IR * F + V]
    2.V [BR] [IR * F]
    3.V [BR + IR * F

  • 寄存器選擇:

    • 16位寄存器,BR只能選擇BP、BX,IR只能選擇DI、SI,F只能爲1
    • 32位寄存器,BR可選擇任意通用寄存器,IR可選擇除ESP外的任意通用寄存器
  • 操作數的段:

    • 選擇EBX/BX時,段寄存器默認DS
    • 選擇EBP/BP時,段寄存器默認SS

立即尋址

示例:ADD EAX, -1

操作數是一個有符號數,且只能是源操作數(IO寄存器除外)

直接尋址

示例:MOV DS:[20H], CL

操作數在內存中,指明操作數的段(部分情況下可省略),後面緊跟偏移地址EA,EA是一個無符號數
需要注意,操作數類型一定要明確

尋址相關的問題

顯示/隱含操作數

一些指令顯示的指明操作數,有些則相反

各尋址方式的關係

根據操作數存放的位置,尋址方式分爲三類:

  • 寄存器方式:寄存器尋址
  • 存儲器方式:寄存器間接尋址,變址尋址,基址加變址尋址,直接尋址
  • 立即方式:立即尋址

源操作數和目的操作數的存放位置

  • 對於雙操作數的指令,源操作數和目的操作數不能同時使用存儲器方式,也就是說不能都來自於內存
  • 立即尋址的操作數,只能是源操作數

寄存器方式尋址的操作數,其數據類型是不明確的,必要情況下,需要額外聲明

  • BYTE PTR
  • WORD PTR
  • DWORD PTR

段選擇說明

  • 如果不希望使用默認段寄存器,也可以顯式地指定,也就是在對應的尋址方式表達式之前,加上段超越前綴(跨段前綴)
  • 段超越前綴可以使用任意段寄存器
  • 不受跨段前綴影響的情況
    • 取指令時,只能是CS段
    • 壓棧和出棧,只能是SS段
    • 串操作中,目的串只能是ES段
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章