计算机程序基础教程(05):x86程序执行流程控制指令
跳转指令用于让指令跳转执行,它会修改CS/IP的值,修改方式是对CS/IP进行加法运算,加一个有符号数,可以向前跳转也可以向后跳转。
● 无条件跳转
jmp指令用于无条件跳转到一个地址执行,示例:jmp 0x401040。
call指令用于无条件跳转到一个地址并返回,它在跳转之前会首先将当前顺序执行的下一条指令的地址存储到栈中,之后再执行跳转,新地址处的程序执行完毕后,会执行一条ret指令,ret指令用于将栈中保存的数据写入到IP寄存器,从而实现返回执行。
● 有条件跳转
jcxz指令用于有条件的跳转,跳转条件是CX寄存器为0,不为0则不跳转,顺序执行下一条指令。
除此之外,还有很多通过标志寄存器确定是否执行跳转的指令,这些指令执行之前一般会首先执行数学运算指令、按位逻辑运算指令、cmp比较指令,CPU会根据运算结果修改标志寄存器的值。
cmp比较指令就是减法指令,但是它不保留计算结果,只会根据计算结果设置标志寄存器的ZF、PF、SF、CF、OF位,从而记录两个数据之间的大于、小于、等于关系,有两个地址码,分别指定被减数与减数。
cmp ax,bx ;计算ax-bx,通过计算结果修改标志寄存器。
相关跳转指令如下:
jz,计算结果为0则跳转,执行条件为ZF=1
jnz,计算结果不为0则跳转
js,计算结果为负数则跳转,执行条件为SF=1
jns,计算结果不为负则跳转
jc,进位则跳转,条件为CF=1
jnc,不进位则跳转
jo,溢出则跳转,条件为OF=1
jno,不溢出则跳转
jp,PF位为1则跳转
jpe,PF位为1则跳转,同上
jnp,PF位为0则跳转
jpo,PF位为0则跳转,同上
je,相等则跳转
jne,不相等则跳转
ja,无符号数大于则跳转
jna,无符号数不大于则跳转
jae,无符号数大于或等于则跳转
jnae,无符号数不大于等于则跳转
jb,无符号数小于则跳转
jnb,无符号数不小于则跳转
jbe,无符号数小于等于则跳转
jnbe,无符号数不小于等于则跳转
jg,有符号数大于则跳转
jng,有符号数不大于则跳转
jge,有符号数大于等于则跳转
jnge,有符号数不大于等于则跳转
jl,有符号数小于则跳转
jnl,有符号数不小于则跳转
jle,有符号数小于等于则跳转
jnle,有符号数不小于等于则跳转
上述指令中很多执行条件都相同,比如jz、je都是ZF=1则执行,jc、jb、jnae都是CF=1则执行,它们本质上是同一条指令,指令操作码相同,只不过它们使用了不同的关系描述方式,方便记忆。
● 循环指令
loop用于循环执行一段指令,使用loop向前跳转执行,跳转次数由CX寄存器确定,执行loop指令时,CPU首先将CX寄存器减1,之后判断CX是否为0,不为0则执行loop指令实现一次循环,为0则跳过loop指令,执行下一条指令。
很多情况下循环条件在编程期间都不能确定,而是在程序执行期间确定,此时可以通过有条件跳转指令实现循环。
● 中断指令
int指令用于发出一个自定义编号内中断,并将CS、IP、标志寄存器入栈存储,有一个地址码,指定中断编号,使用立即数寻址,int 3。
iret指令用于将栈中的数据取出并写入CS、IP、标志寄存器,中断处理程序执行完毕后会使用iret指令返回之前的程序执行。