轉(zhuǎn)移指令的原理
可以修改IP,或同時(shí)修改CS和IP的指令統(tǒng)稱為轉(zhuǎn)移指令。
概括以講,轉(zhuǎn)移指令就是可以控制CPU執(zhí)行內(nèi)存中某處的代碼的指令。
8086CPU的轉(zhuǎn)移行為有以下幾類:
l 只修改IP時(shí),稱為段內(nèi)轉(zhuǎn)移,比如:jmp ax。
l 同時(shí)修改CS和IP時(shí),稱為段間轉(zhuǎn)移,比如:jmp 1000:0。
由于轉(zhuǎn)移指令對(duì)IP的修改范圍不同,段內(nèi)轉(zhuǎn)換又分為:短轉(zhuǎn)移和近轉(zhuǎn)移。
l 短轉(zhuǎn)移IP的修改范圍為-128~127。
l 近轉(zhuǎn)移IP的修改范圍為-32768~32767。
8086CPU的轉(zhuǎn)移指令分為以下幾類:
l 無(wú)條件轉(zhuǎn)移指令(如:jmp)
l 條件轉(zhuǎn)移指令
l 循環(huán)指令(如:loop)
l 過(guò)程
l 中斷
這些轉(zhuǎn)移指令轉(zhuǎn)移的前提條件可能不同,但轉(zhuǎn)移的基本原理是相同的。
操作符offset
操作符offset在匯編語(yǔ)言中是由編譯器處理的符號(hào),它的功能是取得標(biāo)號(hào)的偏移地址。如:
assume cs:codesg
codesg segment
start: mov ax, offset start ;相當(dāng)于mov ax,0
s:mov ax, offset s ;相當(dāng)于mov ax,3
codesg ends
end start
jmp指令
jmp為無(wú)條件轉(zhuǎn)移指令,可以只修改IP,也可以同時(shí)修改CS和IP。
jmp指令要給出兩種信息:
l 轉(zhuǎn)移的目的地址
l 轉(zhuǎn)移的距離(段間轉(zhuǎn)移、段內(nèi)短轉(zhuǎn)移、段人近轉(zhuǎn)移)
依據(jù)位移進(jìn)行轉(zhuǎn)移的jmp指令
jmp short 標(biāo)號(hào)(轉(zhuǎn)到標(biāo)號(hào)處執(zhí)行指令)
這種格式的jmp指令實(shí)現(xiàn)的是段內(nèi)短轉(zhuǎn)移,它對(duì)IP的修改范圍為-128~127,也就是說(shuō),它向前轉(zhuǎn)移時(shí)可以最多越過(guò)128個(gè)字節(jié),向后轉(zhuǎn)移可以最多越過(guò)127個(gè)字節(jié)。
jmp指令中的“short”符號(hào),說(shuō)明指令進(jìn)行的是短轉(zhuǎn)移。
jmp指令中的“標(biāo)號(hào)”是代碼段中的標(biāo)號(hào),指明了指令要轉(zhuǎn)移的目的地,轉(zhuǎn)移指令結(jié)束后,CS:IP應(yīng)該指向標(biāo)號(hào)處的指令。
比如:
assume cs:codesg
codesg segment
start: mov ax,0
mov bx,0
jmp short s
add ax,1
s: inc ax
codesg ends
end start
CPU在執(zhí)行jmp指令的時(shí)候并不需要轉(zhuǎn)移的目的地址。
在“jmp short 標(biāo)號(hào)”指令所對(duì)應(yīng)的機(jī)器碼中,并不包含轉(zhuǎn)移的目的地址,而包含的是轉(zhuǎn)移的位移,這個(gè)位移,是編譯器根據(jù)匯編指令中的“標(biāo)號(hào)”計(jì)算出來(lái)的。
實(shí)際上,指令“jmp short 標(biāo)號(hào)”的功能為:(IP)=(IP)+8位位移。
(1)8位位移=“標(biāo)號(hào)”處的地址-jmp指令后的第一個(gè)字節(jié)的地址;
(2)short指明此處的位移為8位移;
(3)8位位移的范圍為-128~127,用補(bǔ)碼表示;
(4)8位位移由編譯器在編譯時(shí)算出。
還有一種和指令“jmp short 標(biāo)號(hào)”功能相近的指令格式:jmp near prt 標(biāo)號(hào),它實(shí)現(xiàn)的是段內(nèi)近轉(zhuǎn)移。
指令“jmp near ptr 標(biāo)號(hào)”的功能為:(IP)=(IP)+16位位移。
(1)16位位移=指令“標(biāo)號(hào)”處的地址-jmp指令后的第一個(gè)字節(jié)的地址;
(2)near ptr指明此處的位移為16位位移,進(jìn)行的是段內(nèi)近轉(zhuǎn)移;
(3)16位位移的范圍為-32768~32767,用補(bǔ)碼表示。
(4)16位位移由編譯器程序在編譯時(shí)算出。
轉(zhuǎn)移的目的地址在指令中的jmp指令
前面講的jmp指令,其對(duì)應(yīng)的機(jī)器指令中并沒(méi)有轉(zhuǎn)移的目的地址,而是相對(duì)于當(dāng)前IP的轉(zhuǎn)移地址。
指令“jmp far ptr 標(biāo)號(hào)”實(shí)現(xiàn)的是段間轉(zhuǎn)移,又稱為遠(yuǎn)轉(zhuǎn)移。功能如下:
(CS)=標(biāo)號(hào)所在段的段地址;(IP)=標(biāo)號(hào)所在段中的偏移地址。
far ptr指明了指令用標(biāo)號(hào)的段地址和偏移地址修改CS和IP。
轉(zhuǎn)移地址在寄存器中的jmp指令
指令格式:jmp 16位寄存器
功能:(IP)=(16位寄存器)
轉(zhuǎn)移地址在內(nèi)存中的jmp指令
有兩種格式:
(1) jmp word ptr 內(nèi)存單元地址(段內(nèi)轉(zhuǎn)移)
功能:從內(nèi)存單元地址處開始存放著一個(gè)字,是轉(zhuǎn)移的目的偏移地址。
內(nèi)存單元寺睛可用尋址方式的任一格式給出。比如:
mov ax,0123H
mov ds:[0],ax
jmp word ptr ds:[0]
執(zhí)行后,(IP)=0123H。
又如:
mov ax,0123H
mov [bx],ax
jmp word ptr [bx]
執(zhí)行后,(IP)=0123H
(2) jmp dword ptr 內(nèi)存單元地址(段間轉(zhuǎn)移)
功能:從內(nèi)存單元地址處開始存放著兩個(gè)字,高地址處的字是轉(zhuǎn)移的目的段地址,低地址處是轉(zhuǎn)移的目的偏移地址。
(CS)=(內(nèi)存單元地址+2)
(IP)=(內(nèi)存單元地址)
內(nèi)存單元地址可用尋址方式的任一格式給出。如:
mov ax,0123H
mov ds:[0],ax
mov word ptr ds:[2],0
jmp dword ptr ds:[0]
執(zhí)行后,(CS)=0,(IP)=0123H,CS:IP指向0000:0123。
又如,
mov ax,0123H
mov [bx],ax
mov word ptr [bx+2],0
jmp dword ptr [bx]
執(zhí)行后,(CS)=0,(IP)=0123H,CS:IP指向0000:0123。
jcxz指令
jcxz指令為有條件轉(zhuǎn)移指令,所有的有條件轉(zhuǎn)移指令都是短轉(zhuǎn)移,在對(duì)應(yīng)的機(jī)器碼中包含轉(zhuǎn)移的位移,而不是目的地址。對(duì)IP的修改范圍都為:-128~127。
指令格式:jcxz 標(biāo)號(hào)(如果(cx)=0, 轉(zhuǎn)移到標(biāo)號(hào)處執(zhí)行。)
操作:當(dāng)(cx)=0時(shí),(IP)=(IP)+8位位移;
8位位移=“標(biāo)號(hào)”處的地址-jczx指令后的第一個(gè)字節(jié)的地址;
8位位移的范圍為-128~127,用補(bǔ)碼表示;
8位位移由編譯器在編譯時(shí)算出。
當(dāng)(cx不等于0時(shí)),什么也不做(程序向下執(zhí)行)。
指令“jcxz 標(biāo)號(hào)”的功能相當(dāng)于:
if (cx)==0 jmp short 標(biāo)號(hào);
loop指令
loop指令為循環(huán)指令,所有的循環(huán)指令都是短轉(zhuǎn)移,在對(duì)應(yīng)的機(jī)器碼中包含轉(zhuǎn)移的位移,而不是目的地址。對(duì)IP的修改范圍都為:-128~127。
指令格式:loop 標(biāo)號(hào)((cx)=(cx)-1,如果(cx)≠0,轉(zhuǎn)移到標(biāo)號(hào)處執(zhí)行。)
操作:(1)(cx)=(cx)-1
(2) 如果(cx)≠0,(IP)=(IP)+8位位移。
8位位移=“標(biāo)號(hào)”處的地址-loop指令后的第一個(gè)字節(jié)的地址;
8位位移的范圍為-128~127,用補(bǔ)碼表示;
8位位移由編譯器在編譯時(shí)算出。
如果(cx)=0,什么也不做(程序向下執(zhí)行)。
指令“loop 標(biāo)號(hào)”的功能相當(dāng)于:
(cx)--;
if ( (cx)≠0) jmp short 標(biāo)號(hào);
根據(jù)位移進(jìn)行轉(zhuǎn)移的意義
jmp short 標(biāo)號(hào)
jmp near ptr 標(biāo)號(hào)
jcxz 標(biāo)號(hào)
loop 標(biāo)號(hào)
它們對(duì)IP的修改是根據(jù)轉(zhuǎn)移目的地址和轉(zhuǎn)移起始地址之間的位移來(lái)進(jìn)行的。
在它們對(duì)應(yīng)的機(jī)器碼中不包含轉(zhuǎn)移的目的地址,而包含的是到目的地址的位移。
這種設(shè)計(jì),方便了程序段在內(nèi)存中的浮動(dòng)裝配。
編譯器對(duì)轉(zhuǎn)移位移超界的檢測(cè)
根據(jù)位移進(jìn)行轉(zhuǎn)移的指令,它們?cè)谵D(zhuǎn)移范圍受到轉(zhuǎn)移位移的限制,如果在源程序中出現(xiàn)了轉(zhuǎn)移范圍超界的問(wèn)題,在編譯的時(shí)候,編譯器將報(bào)錯(cuò)。