彙編 儲存器取資料和位址跳轉的定址方式

2021-10-13 10:16:30 字數 2756 閱讀 1521

在編寫彙編**的時候,我們經常需要取出各種各樣的資料,進行操作,

但是有的資料常數(這裡叫立即數),還有的在暫存器中,都是很簡單的,但是難免有一些在儲存器中,這時我們就需要取出資料進行操作。

在分支結構或者迴圈結構中,我們可能需要跳過幾行(if else語句)或者回到幾行之間(迴圈),

所以我們需要修改儲存當前指令的ip暫存器,為其賦值的過程中我們就需要賦值,道理同上。

在例子中,我們經常使用的是mov ax,……,這裡要說明一下,定址方式不一定非要是mov指令,而且mov指令這樣的兩個運算元都可以採用定址方式。

先講一下位址的形成:

8086是20位的位址線,但是我們的暫存器是16位的,剩下的四位不能浪費了,所以人們就想出附加段暫存器的方式(下面的配對中,前面的都是附加段暫存器)。

將附加段暫存器的內容乘10h,然後加上偏移位址(ea),這樣我們就得到了乙個20位的位址。

我們將20位的位址叫做實體地址(pa)。

接下來需要求的就是ea。

給出常用的暫存器配對:

如果不是串部分,我們的di暫存器都配合ds使用。

另外我們還有跨段定址,就是不按照預設的暫存器來,如:mov ax,ds:[bp]

mov ax,10h

mov ax,bx

乙個是將10h的內容賦值給ax,另乙個是將bx的內容賦值給ax。

使用立即數或者是暫存器的資料賦值,都不需要在儲存器中尋找資料,還是很快的。

定址說白了就是從乙個有效位址中讀取乙個資料,賦值給物件(或者是將資料賦值給位址指向的地方)

mov al,[1000h]

直接將位址給出,然後我們將位址對應的內容賦值給al暫存器(不是直接塞位址過去)

注意區分一下mov ax,[1000h]和mov ax,1000h

間接就是不直接給出顯式位址,而是存在暫存器中,我們需要自己去算有效位址(當然是計算機幫你算了)。

格式:mov ax,[bx] ,

這裡能使用的暫存器只有幾個:bx 、bp、si、di,只需要匹配預設的段暫存器然後算出20位位址,將位址上的資料送進ax就行。

區分mov ax,bx

相對,我們可以想象成乙個陣列,我們只知道其首位址是不能直接得到我們想要的內容,所以我們需要有乙個相對位址來找到元素。

格式:mov ax,[bx+60h]或mov ax,60h[bx]

這裡面的常數我們叫做偏移量,為八位或者十六位(注意是有符號數)

找到對應的附加段,然後將60h也加到實體地址上,得到我們最終的位址,然後取值、賦值即可。

這裡我們區分一下四個暫存器,接下來會用到

基址暫存器:bx、bp

變址暫存器:si、di

mov bx, [bx+si]

這裡我們需要用到乙個基址暫存器和乙個變址暫存器,將兩者求和再加上對應的段暫存器就能找到實體地址。

那麼我們是使用哪個暫存器的對應段暫存器呢?

解釋一下兩個暫存器的定義:

用基址表示首位址,

而用變址來表示陣列,**或者字串中的某乙個值

很明顯,我們應該採取的是基址暫存器對應的段暫存器。

一直在用陣列舉例子,其實暫存器相對定址和基址變址定址是可以聯絡上一維陣列的。

間接就是隱晦,就是不直接給出,需要我們自己讀取一下;

相對就是有常數偏移量,變址就是要加上乙個暫存器的內容(也算是偏移量),相當於一維陣列

相對基址變址就是二維陣列,首位址+變址+偏移量

暫存器運算元位址只能由bx、bp、si、di 給出, 它們的組合也不是任意的。

就是修改當前的指令位址(ip暫存器中),賦值方式和上面差不多

分為直接和間接,也就是是否直接給出位址。

如果是直接**jmp short next(next為結束在的位置,是乙個位址)

short是8位位移量,near ptr是16位。(不是結束位址)

jmp是跳轉指令。

雖然我們是直接給出跳轉位址的位置,但是在機器指令中(我們寫的是偽指令)顯示的是位移量,也就是差值。

間接跳轉的話,我們採取的是jmp word ptr +間接定址。

這裡的形式不止一種,比如jmp [bp]和jmp [bx][si]都是有的。

這裡我們新增word ptr的目的是因為我們需要在後面給出的位址中取值,其中取值的型別需要確定。

可能有一點繞,想一下我們的目的就是取出乙個位址,而我們採用的是間接,所以就是找到乙個位址,從該位址上取我們需要的位址。(位址為乙個字的大小)

然後我們在找到位址之後,我們需要取出乙個字的內容,作為我們跳轉的目的地,但是如果是jmp+間接位址,其實計算機是不知道我們想取出的資料的型別的,這裡就需要加上word ptr告訴計算機我們要取乙個字的大小。

但如果是暫存器間接定址,我們直接拿出暫存器的位址,可以確定大小是乙個字,所以word ptr就不需要了。

段內是只修改ip,如果是段間轉移,我們則需要修改cs和ip。

也是分為直接和間接。

如果是段間間接定址,那麼我們需要先找到乙個實體地址,還是採取讀數的方式。

不過之前都是暫存器為幾位就讀取幾位,這次我們採取不一樣的方式。

儲存器分段和位址的形成

從8086開始採用分段的方法管理儲存器。只有充分理解儲存器分段的概念和儲存器邏輯位址和實體地址的關係,才能熟練地使用8086 8088組合語言。儲存單元的位址是無符號數,n 位二進位制數總共能夠表示 2n 個儲存單元的位址。為了書寫方便,儲存單元位址常採用十六進製制數表示。當以字方式訪問字時,處理器...

資料結構中的 作引用和取位址符的區別和作用

引用就是某一變數 目標 的乙個別名,對引用的操作與對變數直接操作完全一樣。作為引用的時候,必須在定義時候就進行初始化,若不進行初始化則會編譯報錯。int c int ic c 即c的身份被ic替代,對ic的操作就相當於對c的操作。int function int i 引用同樣可以出現在函式的形參中。...

彙編32位暫存器和位址編號的五種書寫形式

32位通用暫存器 32位 eax ebx ecx edx esp ebp esi edi 每個暫存器的最大寬度是32位 16位 ax bx cx dx sp bp si di 8位 al bl cl dl ah bh ch dh 想暫存器存乙個數字可以用mov指令 mov eax,1 就是把1存到e...