0%

X86指令体系中的控制转移指令

前言:学习X86指令体系中的控制转移指令

无条件转移指令

指令格式:JMP LABLE

LABLE是将要转移到的目标地址,那LABLE是否与当前指令在一个代码段,无条件转移可分为段内转移(16位地址)和段间转移(20位地址);而按LABLE的不同寻址方式又可以分为直接寻址间接寻址

直接寻址:转移地址在指令代码中

间接地址:转移地址在寄存器或内存单元

段内转移

在当前代码段范围64KB内转移(±32KB范围)成为近转移(NEAR PTR)。转移范围在段内-128至+127范围内称为短转移(SHORT)。段内转移CS段地址不变只要改变IP的偏移地址

1
2
3
4
JMP SHORT LABLE  ;短转移,直接寻址,目标地址为LABLE
LMP NEAR PTR LABLE ;近转移,直接寻址,目标地址为LABLE(NEAR不写)(NEAR不写默认是段内近转移)
JMP SI ;间接寻址,目标地址在SI寄存器中(IP的内容由SI提供)
JMP WORD PTR [BX] ;间接寻址,目标地址在内存单元中(执行完后IP = BX的地址为内容,地址内容才是转移的部分)

段间转移

远转移(FAR PTR)从当前代码段转移到另一个代码段(设为代码段2),转移范围为1MB。需要改变CS段地址和IP段地址。因此目标地址必须用一个32位数表达

1
2
JMP  FAR PTR LABLE ;远转移到代码段2的LABLE,IP ← [LABLE],CS ← [代码段2的段地址]
JMP FAR PTR MEM ;MEM是内存单元的地址,从MEM开始的4个连续单元中存放着2个16位的地址,一个是目标地址的偏移地址,一个是目标地址的段地址,即IP ← [MEM],CS ← [MEM + 2]

条件转移语句JCC

条件转移语句都是段内短转移

条件转移指令的一般格式:JCC LABLE(没这个指令,表示形式)

指令功能:如满足条件,则发生转移:IP ← IP + 8位偏移量;若条件不满足,则不转移,顺序执行下一条指令。转移范围与JMP SHORT指令相同

指令中的条件即为状态标志的状态,条件转移指令可以分为三类:判断单个标志位状态、比较无符号数高低、比较有符号数大小

判断单个标志位状态

  1. JZ/JE和JNZ/JNE:利用零标志位ZF,判断结果是否为零(或相等)
  2. JS和JNS:利用符号标志位SF,判断结果是正是负
  3. JO和JNO:利用溢出标志位OF,判断结果是否产生溢出
  4. JP/JPE和JNP/JPO:利用奇偶标志位PF,判断结果中”1”的个数是偶还是奇
  5. JC/JB/JNAE和JNC/JNB/JAE:利用进位标志CF,判断结果是否进位或错位在这里插入图片描述

指令中的Z、S、O、C、P分别表示标志寄存器中的ZF 、SF、OF、CF、PF标志位,指令中的N表示不等(Not),E表示相等(Equal)

比较无符号数高低(条件为一个标志或标志组合)

比较无符号数用高低表示。指令中A表示高(Above),B表示低(Below),利用CF确定高低,利用ZF确定相等

image-20240422221226926

比较有符号数大小(条件为标志组合)

判断有符号数的大小需要组合OF、SF标志,并利用ZF标志确定相等。指令的G表示大(Great),L表示小(Less)

image-20240422221518167

测试CX的值为0,则转移的指令

指令格式:JCXZ LABLE

指令功能:若CX的寄存器的内容为零,则转移到指定地址标号处

循环控制指令

循环指令默认利用CX计数器,属于段内短转移

指令格式:

LOOP LABLE

  • 执行前CX先减1,如果不为0,则转到LABLE执行,否则顺序执行

LOOPZ/LOOPE LABLE

  • 执行前CX先减1,如果不为0且ZF = 1,则转到LABLE执行,否则顺序执行

LOOPNZ/LOOPNE LABLE

  • 执行前CX先减1,如果不为0且ZF = 0,则转到LABLE执行,否则顺序执行

子程序条用及返回指令

子程序调用指令CALL

CALL指令位于主程序,CALL调用的子程序与CALL指令可以处于同一代码段内,也可以在不同的代码段,因而分段内调用和段间调用。段内直接调用、段内间接调用、段间直接调用、段间间接调用

指令中”NEAR PTR“表示段内调用,”FAR PTR“表示段间调用。汇编程序自动识别”段内”,故可以省略

返回指令RET为子程序最后执行的指令,作用为断点出栈,将堆栈中存放的CALL指令的下一条指令的段地址、偏移地址送给CS、IP(低位CS、高位IP)

RET指令根据段内和段间、有无参数,分成四种类型,需要弹出CALL指令压入堆栈的返回地址

指令格式:

  1. RET ;无参数段内返回
  2. RET n ;有参数段内返回
  3. RET ;无参数段间返回
  4. RET n ;有参数段间返回

段内返回的功能:偏移地址IP出栈,IP ← SS:[SP],SP ← SP + 2

段间返回的功能:偏移地址IP和段地址CS出栈,IP ← SS:[SP],SP ← SP + 2,CS ← SS:[SP],SP ← SP + 2

RET n为有参数返回,n为1个16位立即数,则堆栈指针SP将增加,即SP ← SP + n。主要用于程序可以方便地从堆栈中去除若干个执行CALL指令以前的入栈的参数