在別的語言中蘸吓,程序進(jìn)行跳轉(zhuǎn)被看作是一種邏輯上的漏洞善炫,想必學(xué)習(xí)過C語言的人都有這種認(rèn)識,就是最好不要在程序中出現(xiàn)GOTO這個指令库继,不過箩艺,跳轉(zhuǎn)在匯編語言中卻是一種很重要的語法,理解跳轉(zhuǎn)指令才能更好的駕馭匯編宪萄。
1.jmp指令
jmp指令是無條件的跳轉(zhuǎn)指令艺谆,jmp分為3種跳轉(zhuǎn)模式,一種是短轉(zhuǎn)移拜英,一種是近轉(zhuǎn)移静汤,最后是遠(yuǎn)轉(zhuǎn)移。首先介紹一下前兩種跳轉(zhuǎn):
jmp short 標(biāo)號?????????????? 居凶;短轉(zhuǎn)移虫给,程序跳轉(zhuǎn)到標(biāo)號標(biāo)注的地方,和C語言中的goto指令類似
jmp near prt 標(biāo)號?????????? 侠碧;近轉(zhuǎn)移抹估,和短轉(zhuǎn)移類似
這兩種跳轉(zhuǎn)指令是不需要加上跳轉(zhuǎn)的地址的,他們屬于段內(nèi)跳轉(zhuǎn)指令弄兜,也就是說药蜻,他們只能改變IP的指向瓷式,而不改變CS的指向,他們跳轉(zhuǎn)依靠的是位移语泽,這是編譯器在編譯的時候處理的事情贸典,編譯器會將你的標(biāo)號地址減去jmp指令的地址,計算出之間位移踱卵,然后在翻譯成機(jī)器語言瓤漏。位移為正就是向下跳轉(zhuǎn),位移為負(fù)就是向上跳轉(zhuǎn)颊埃。short和near prt之間的差別就是short跳轉(zhuǎn)的極限是2^7(8位位移)蔬充,near的極限是2^15(16位位移)。
jmp far prt 標(biāo)號???????????? 班利;遠(yuǎn)轉(zhuǎn)移饥漫,和短轉(zhuǎn)移意思類似,只是細(xì)節(jié)不同
遠(yuǎn)轉(zhuǎn)移罗标,又稱為段間轉(zhuǎn)移庸队,它不僅僅會修改IP指向,還會修改CS的指向闯割,這個跳轉(zhuǎn)的依據(jù)就是實實在在的地址彻消。
那么,現(xiàn)在請思考為什么計算機(jī)會提供3種跳轉(zhuǎn)模式宙拉,或者說宾尚,為什么要出現(xiàn)依靠位移的跳轉(zhuǎn)指令,全部依靠絕對地址來跳轉(zhuǎn)難道不好嗎谢澈?
工程師絕對不會做出費(fèi)力不討好的事情煌贴,那么出現(xiàn)依靠位移的跳轉(zhuǎn)指令就一定有他的優(yōu)勢存在,思考以下情形锥忿,程序在內(nèi)存中運(yùn)行之時是需要被加載的牛郑,這個加載到的內(nèi)存地址是不確定的,也就是說在這種情況之下敬鬓,我們的遠(yuǎn)轉(zhuǎn)移指令很有可能找尋不到我們想要找尋的地址淹朋,那這時,相等地址(位移)的優(yōu)勢就體現(xiàn)出來了钉答,我們可以依靠位移來精確定位這個段中任意一個地址(在內(nèi)存中的浮動裝配)础芍,而不需要具體的地址,但是這也引發(fā)了一個很奇怪的程序希痴,我們最后再來介紹者甲。
2.loop,jcxz指令
loop指令春感,顧名思義砌创,就是循環(huán)指令虏缸,語法和jmp指令類似:
loop 標(biāo)號???????????????????????? ;跳轉(zhuǎn)到標(biāo)號處
還記得前面介紹的CX寄存器嗎嫩实,這里就是輪到他大顯生手的地方了刽辙,loop指令是依靠CX的值來判斷循環(huán)次數(shù)的,只要CX不為0甲献,那么loop就執(zhí)行跳轉(zhuǎn)宰缤,那么loop指令用偽代碼來描述就是:
if(CX != 0)? dec CX? jmp 標(biāo)號??????? 晃洒;dec是自減的意思
那么有了CX不為0慨灭,則跳轉(zhuǎn)的指令,有沒有另一個當(dāng)CX等于0時球及,跳轉(zhuǎn)的指令氧骤?當(dāng)然,jcxz指令就是這種功能吃引,看字面意思就是jmp (cx = zore)筹陵,jcxz指令用法和jmp完全一致,只是jcxz執(zhí)行之時首先會去檢查CX寄存器的值镊尺。
3.一段奇怪的程序
好的朦佩,現(xiàn)在是不是很好奇之前所提到過的那個很奇怪的程序,那么我們現(xiàn)在開始介紹庐氮,想必在理解過這段奇怪的程序之后语稠,你會對jmp這個指令有著更加深入的理解。
這是這本書的作者弄砍,王爽老師提供的程序颅筋,下面上圖:
現(xiàn)在思考,這個程序運(yùn)行是怎么樣運(yùn)行输枯?他能正常退出嗎议泵,也就是執(zhí)行到程序退出的出口。
如果你認(rèn)為它可以正常的退出桃熄,那么恭喜你先口,你已經(jīng)理解jmp指令了,如果你認(rèn)為它是在標(biāo)號S1,S2處不斷的循環(huán)瞳收,那么請仔細(xì)回顧一下一開始所說的短轉(zhuǎn)移指令碉京。
是的,這里的短轉(zhuǎn)移指令最后翻譯出來的意思是向上移動S2-S1(地址)個字節(jié)螟深,于是程序最后就在標(biāo)號S處向上跳轉(zhuǎn)到了這個段的最開頭谐宙,也就是程序的出口,成功退出界弧。