轉移指令的原理


可以修改IP,或者同時修改cs和ip的指令統稱為轉移指令。
8086cpu的轉移行為有以下幾類:

  • 只修改ip,稱為段內轉移,如jmp ax
  • 同時修改cs和ip,稱為段間轉移,如jmp 1000:0

根據轉移指令對於ip的修改范圍不同,所以段內轉移又分為:短轉移和近轉移

  • 短轉移IP的修改返回為-128~127
  • 近轉移IP的修改范圍為-32768~32767

8086cpu的轉移指令分為以下幾類:

  • 無條件轉移指令(如:jmp)
  • 條件轉移指令 (jcxz)
  • 循環指令(loop)
  • 過程
  • 中斷

不同轉移指令的轉移條件可能不同,但是轉移的基本原理是相同的

操作符offset

offset是在匯編語言中是由編譯器處理的符號,功能為取得標號的偏移地址。也就是相對於代碼段的偏移地址,就是直接IP值了。

jmp指令

jmp為無條件轉移指令,可以只修改IP,也可以同時修改cs和ip。
jmp指令需要給出兩種信息:

  • 轉移的目的地址
  • 轉移的距離(段間轉移,段內短轉移,段內近轉移)

不同的給出目的地址的方法不同,和不同的轉移位置,對應有不同格式的jmp指令。

依據位移進行轉移的jmp指令

  1. jmp short 標號 (IP)=(IP)+8位位移
    這種格式的jmp指令實現的是段內短轉移。對ip的修改范圍限定為-128~127之間,可以看出正好是一個字節能夠表示的范圍。
  2. jmp near ptr 標號 (IP)=(IP)+16位位移
    jmp short功能相同,只不過他實現的是段內近轉移。簡單來說就是轉移的距離拉長(雖然仍然是在段內)

小貼士
可以看到jmp shortjmp near ptr(段內轉移)並沒有直接將轉移的目的地址直接寫入機器指令中。而是將一個相對偏移地址寫入了機器指令。(但是debug在對應的匯編指令中會看到偏移地址)
具體來說就是將標號地址相對於jmp指令的下一條指令的地址寫入了機器指令。
也就是說,cpu在執行jmp指令的時候並不需要轉移的目標地址。
UTOOLS1561367196752.png

轉移的目的地址在指令中的jmp指令

前面講到的段內轉移指令其機器指令中並沒有轉移的目的地址,而是相對於當前ip的轉移位移。
jmp far ptr 標號實現段間轉移,又稱為遠轉移。
(CS)=標號所在段的段地址;(IP)=標號在段中的偏移地址
far ptr將標號的地址寫入了匯編指令。
UTOOLS1561367856893.png

jmp指令的機器碼為EA,可以很明顯的看出來,其中高地址放段地址,低地址放偏移地址。
順便說明,像是jmp 1000:0是在debug中使用的,在匯編代碼中並不能使用這樣的指令。

轉移地址在寄存器中的jmp指令

指令格式: jmp 16位reg
功能: (IP)=(16位reg)

轉移地址在內存中的jmp指令

轉移地址在內存中的jmp指令有兩種格式:

  1. jmp word ptr 內存單元地址(段內轉移)
    更改ip值。
  2. jmp dword ptr 內存單元地址(段間轉移)
    目標內存中放着兩個字,其中高地址處的字為轉移目標的段地址,低地址處的字為轉移的目標的段偏移地址。
    (CS)=(內存單元地址+2)
    (IP)=(內存單元地址)

jcxz指令

jcxz為條件轉移指令。所有的條件轉移指令都是短轉移指令,在對應的機器碼中包含轉移的位移,而不是目的地址。對IP的修改范圍為-128~127.
功能:當cx寄存器的值為0是執行轉移,否則什么也不做。

loop指令

loop指令為循環指令,所有的循環指令都是短轉移。

根據位移進行轉移的意義

高端大氣的說法就是方便了程序段在內存中的浮動裝配
實際上就是無所謂程序在內存中的地址,程序中的轉移指令無需改變。

編譯器對於轉移位移超界的檢測

根據位移進行轉移的指令,他們的轉移范圍收到轉移位移的限制,如果在源程序中出現了轉移范圍超界的問題,在編譯的時候,編譯器將會報錯。

分析一個奇怪的程序

就是一個計算通過相對偏移位置計算偏移位置的問題。
UTOOLS1561372732806.png

會注意到在執行完mov cs:[di], ax以后,s段的9090(nop nop)變成了EBF6(值為F6EB【小端序】)。同時想到的是同樣都是EBF6卻翻譯出了不同的匯編指令。然而實際上都是相同的,翻譯的問題是編譯器做的。他將機器碼翻譯了以下,也就是將相對偏移地址直接翻譯成為了IP中的偏移地址。
即使上面講到過的偏移地址=jmp的下一條指令地址+相對偏移地址(注意到F6的問題,計算機中的數據以補碼方式存儲)。他就是將偏移地址算了出來。

根據材料編程

答案:

assume cs:code, ds:data
data segment
 db 'welcome to masm!' ; 文字
 db 00000010B, 00100100B, 01110001B ; 屬性
data ends

code segment
start:
 mov ax, data
 mov ds, ax

 mov ax, 0b800H 
 mov es, ax 

 mov bx, 0
 mov si, 0
 mov di, 64
 mov bp, 6e0H 

 mov cx, 3
ln: 
 mov dx, cx
 mov cx, 16

 mov bx, 0
 mov di, 64
s:
 mov al, [bx]
 mov ah, 16[si]
 mov es:[bp].[di], ax

 inc bx
 add di, 2
 loop s

 add si, 1
 add bp, 160
 mov cx, dx
 loop ln

 mov ax, 4c00H
 int 21H

code ends
end start

注意數值不能以字母開頭






免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM