計算機程序基礎(chǔ)教程(05):x86程序執(zhí)行流程控制指令
跳轉(zhuǎn)指令用于讓指令跳轉(zhuǎn)執(zhí)行,它會修改CS/IP的值,修改方式是對CS/IP進行加法運算,加一個有符號數(shù),可以向前跳轉(zhuǎn)也可以向后跳轉(zhuǎn)。
?● 無條件跳轉(zhuǎn)
jmp指令用于無條件跳轉(zhuǎn)到一個地址執(zhí)行,示例:jmp 0x401040。
call指令用于無條件跳轉(zhuǎn)到一個地址并返回,它在跳轉(zhuǎn)之前會首先將當(dāng)前順序執(zhí)行的下一條指令的地址存儲到棧中,之后再執(zhí)行跳轉(zhuǎn),新地址處的程序執(zhí)行完畢后,會執(zhí)行一條ret指令,ret指令用于將棧中保存的數(shù)據(jù)寫入到IP寄存器,從而實現(xiàn)返回執(zhí)行。
?● 有條件跳轉(zhuǎn)
jcxz指令用于有條件的跳轉(zhuǎn),跳轉(zhuǎn)條件是CX寄存器為0,不為0則不跳轉(zhuǎn),順序執(zhí)行下一條指令。
除此之外,還有很多通過標(biāo)志寄存器確定是否執(zhí)行跳轉(zhuǎn)的指令,這些指令執(zhí)行之前一般會首先執(zhí)行數(shù)學(xué)運算指令、按位邏輯運算指令、cmp比較指令,CPU會根據(jù)運算結(jié)果修改標(biāo)志寄存器的值。
cmp比較指令就是減法指令,但是它不保留計算結(jié)果,只會根據(jù)計算結(jié)果設(shè)置標(biāo)志寄存器的ZF、PF、SF、CF、OF位,從而記錄兩個數(shù)據(jù)之間的大于、小于、等于關(guān)系,有兩個地址碼,分別指定被減數(shù)與減數(shù)。
cmp ax,bx? ? ;計算ax-bx,通過計算結(jié)果修改標(biāo)志寄存器。
相關(guān)跳轉(zhuǎn)指令如下:
jz,計算結(jié)果為0則跳轉(zhuǎn),執(zhí)行條件為ZF=1
jnz,計算結(jié)果不為0則跳轉(zhuǎn)
js,計算結(jié)果為負數(shù)則跳轉(zhuǎn),執(zhí)行條件為SF=1
jns,計算結(jié)果不為負則跳轉(zhuǎn)
jc,進位則跳轉(zhuǎn),條件為CF=1
jnc,不進位則跳轉(zhuǎn)
jo,溢出則跳轉(zhuǎn),條件為OF=1
jno,不溢出則跳轉(zhuǎn)
jp,PF位為1則跳轉(zhuǎn)
jpe,PF位為1則跳轉(zhuǎn),同上
jnp,PF位為0則跳轉(zhuǎn)
jpo,PF位為0則跳轉(zhuǎn),同上
je,相等則跳轉(zhuǎn)
jne,不相等則跳轉(zhuǎn)
ja,無符號數(shù)大于則跳轉(zhuǎn)
jna,無符號數(shù)不大于則跳轉(zhuǎn)
jae,無符號數(shù)大于或等于則跳轉(zhuǎn)
jnae,無符號數(shù)不大于等于則跳轉(zhuǎn)
jb,無符號數(shù)小于則跳轉(zhuǎn)
jnb,無符號數(shù)不小于則跳轉(zhuǎn)
jbe,無符號數(shù)小于等于則跳轉(zhuǎn)
jnbe,無符號數(shù)不小于等于則跳轉(zhuǎn)
jg,有符號數(shù)大于則跳轉(zhuǎn)
jng,有符號數(shù)不大于則跳轉(zhuǎn)
jge,有符號數(shù)大于等于則跳轉(zhuǎn)
jnge,有符號數(shù)不大于等于則跳轉(zhuǎn)
jl,有符號數(shù)小于則跳轉(zhuǎn)
jnl,有符號數(shù)不小于則跳轉(zhuǎn)
jle,有符號數(shù)小于等于則跳轉(zhuǎn)
jnle,有符號數(shù)不小于等于則跳轉(zhuǎn)
上述指令中很多執(zhí)行條件都相同,比如jz、je都是ZF=1則執(zhí)行,jc、jb、jnae都是CF=1則執(zhí)行,它們本質(zhì)上是同一條指令,指令操作碼相同,只不過它們使用了不同的關(guān)系描述方式,方便記憶。
?● 循環(huán)指令
loop用于循環(huán)執(zhí)行一段指令,使用loop向前跳轉(zhuǎn)執(zhí)行,跳轉(zhuǎn)次數(shù)由CX寄存器確定,執(zhí)行l(wèi)oop指令時,CPU首先將CX寄存器減1,之后判斷CX是否為0,不為0則執(zhí)行l(wèi)oop指令實現(xiàn)一次循環(huán),為0則跳過loop指令,執(zhí)行下一條指令。
很多情況下循環(huán)條件在編程期間都不能確定,而是在程序執(zhí)行期間確定,此時可以通過有條件跳轉(zhuǎn)指令實現(xiàn)循環(huán)。
?● 中斷指令
int指令用于發(fā)出一個自定義編號內(nèi)中斷,并將CS、IP、標(biāo)志寄存器入棧存儲,有一個地址碼,指定中斷編號,使用立即數(shù)尋址,int 3。
iret指令用于將棧中的數(shù)據(jù)取出并寫入CS、IP、標(biāo)志寄存器,中斷處理程序執(zhí)行完畢后會使用iret指令返回之前的程序執(zhí)行。