汇编语言转移指令&循环指令

Posted BkbK-

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了汇编语言转移指令&循环指令相关的知识,希望对你有一定的参考价值。

转移指令

在这里插入图片描述

一、无条件转移指令

(1)JMP指令概述

JMP 称为无条件转移 (Jump) ,就是无任何先决条件就能使程序改变执行顺序。

  • 执行无条件转移指 JMP, 就可以使程序转到指定的目标地址处,从目标地址处开始执行指令。
  • JMP 指令相当于高级语言的 GOTO 语句 结构化程序设计要求尽量避免使用GOTO 语句,但指令系统决不能缺少 JMP ,汇编语言编程也不可避免地要使用 JMP 指令。

(2)JMP指令类型

JMP 根据目标地址的转移范围和寻址方式,可以分成4种类型。

  • MASM 汇编程序会根据存储模型和目标地址等信息自动识别是段内转移还是段间转移,也能够根据位移 大小自动形成短转移或近转移指令。
  • 32 位保护方式使用平展存储模型,不允许应用程序进行段间转移

1.段内转移、相对寻址

JMP label 	;EIP=EIP+位移量

段内相对转移 JMP指令 利用标号 (LABEL) 指明目标地址。

  • 当向地址增大方向转移时,位移量为正;向地址减小方向转移时,位移量为负(补码表示)。
  • EIP 指向的偏移地址改变,段寄存器 CS 的内容不变

2.段内转移、间接寻址

JMP r32/rl6		 	; EIP = r32/r16 , 寄存器间接寻址
JMP m32/m16 		; EIP = m32/m16 , 存储器间接寻址

段内间接转移 JMP 32 位通用寄存器或主存单元内容(线性地址空间)或者 16位通用寄存器或主存单元内容(实地址存储模型)送入 EIP 寄存器,作为新的指令指针(即偏移地址),但不修改 CS 寄存器的内容。

3.段间转移、直接寻址

JMP label 			; EIP = label 的偏移地址,CS= label 的段选择器

段间直接转移 JMP 是将标号所在的段选择器作为新的 CS 值,标号在该段内的偏移地址作为新的 ElP 这样,程序跳转到新的代码段执行.

4.段间转移、间接寻址

JMP m48/m32 		;EIP=m48/m32 , CS =m48+4/m32+2
  • 在32位线性地址空间用一个字存储单元 (48 位,使用了符号m48) 表示要跳转的目标地址,将低双字送 EIP 寄存器 CS 寄存器(小端方式);
  • 在16位实地址存储模型中,用一个双字存储单元表示要跳转的目标地址,将低字送 EIP 寄存器、高字送入CS 寄存器(小端方式)。

(3)条件转移指令的使用

1.标号的地址属性

使用offset + 标号 获取标号所在指令的地址

  • 指令寄存器间接寻址

    mov eax,offset label
    jmp eax
    
  • 指令存储器间接寻址

    mov eax,offset label
    mov nvar,eax
    jmp nvar
    

2.控制转移

汇编程序提供了短转移SHORT 、近转移 NEAR PTR 和远转移 FAR PTR 操作符,强制转换一个标号、段名或子程序名的类型,形成相应的控制转移。

jmp near ptr label		;强制生成相对寻址的近转移

二、条件转移指令

(1)JCC指令概述

条件转移指令 Jcc 根据指定的条件确定程序是否发生转移,条件满足,发生转移、跳转到 LABEL 位置,即 EIP=EIP+ 位移量。否则,顺序执行下条指令。

  • 语法格式:

    Jcc label
    

    label表示目标地址采用段内相对寻址

  • 流程图表示
    在这里插入图片描述

(2)条件转移指令分类

条件转移指令中的条件是由状态标志决定,共16条指令,分成两类。
在这里插入图片描述

①单个标志状态作为条件

5个状态标志ZF、CF、SF、OF和PF的10种状态

1.利用零位标志ZF的条件转移指令
  • 判断条件:运算结果为0、两数相等(标志ZF=1)

    JZ label ;Jump if Zero
    
    JE label ;Jump if Equal
    
  • 判断条件:结果不为0、不相等(标志ZF=0)

    JNZ label ;Jump if Not Zero
    
    JNE label ;Jump if Not Equal
    
2.利用进位标志CF的条件转移指令
  • 判断条件:运算结果有进位(借位)(标志CF=1)

    JC label ;Jump if Carry
    
  • 判断条件:结果没有进位(借位)(标志CF=0)

    JNC label ;Jump if Not Carry
    
3.利用溢出标志OF的条件转移指令
  • 判断条件:运算结果有溢出(标志OF=1)

    JO label ;Jump if Overflow
    
  • 判断条件:结果没有溢出(标志OF=0)

    JNO label ;Jump if Not Overflow
    
4.利用符号标志SF的条件转移指令
  • 判断条件:运算结果是负、最高位为1(标志SF=1)

    JS label ;Jump if Sign
    
  • 判断条件:结果是正、最高位为0(标志SF=0)

    JNS label ;Jump if Not Sign
    
5.利用奇偶标志PF的条件转移指令
  • 判断条件:低8位结果中1的个数为偶或0(标志PF=1)

    JP label ;Jump if Parity
    
    JPE label ;Jump if Parity Even
    
  • 判断条件:低8位结果中1的个数为奇(标志PF=0)

    JNP label ;Jump if Not Parity
    
    JPO label ;Jump if Parity Odd
    

②两数大小关系作为条件

1.比较无符号整数大小

4种情况:低于、不低于、低于等于、高于
无符号数大小用高(Above)、低(Below)助记符

  • 判断条件:低于、不高于等于(标志CF=1)

    JB ;Jump if Below
    
    JNAE ;Jump if Not Above or Equal
    
  • 判断条件:不低于、高于等于(标志CF=0)

    JNB ;Jump if Not Below
    
    JAE ;Jump if Above or Equal
    
  • 判断条件:低于等于、不高于(标志CF=1或ZF=1)

    JBE ;Jump if Below or Equal
    
    JNA ;Jump if Not Above
    
  • 判断条件:不低于等于、高于(标志CF=0且ZF=0)

    JNBE ;Jump if Not Below or Equal
    
    JA ;Jump if Above
    
2.比较有符号整数大小

4种情况:小于、不小于、小于等于、大于
有符号数大小用大(Greater)、小(Less)助记符

  • 判断条件:小于、不大于等于(标志SF≠OF)

    JL ;Jump if Less
    
    JNGE ;Jump if Not Greater or Equal
    
  • 判断条件:不小于、大于等于(标志SF=OF)

    JNL ;Jump if Not Less
    
    JGE ;Jump if Greater or Equal
    
  • 判断条件:小于等于、不大于(标志SF≠OF或ZF=1)

    JLE ;Jump if Less or Equal
    
    JNG ;Jump if Not Greater
    
  • 判断条件:不小于等于、大于(标志SF=OF且ZF=0)

    JNLE ;Jump if Not Less or Equal
    
    JG ;Jump if Greater
    

(3)产生条件的指令

1.比较指令CMP

进行减法运算,用于判断两个数据大小、是否相等

将目的操作数减去源操作数,差值不回送目的操作数,按照减法结果影响状态标志

CMP reg,imm/reg/mem ;reg-imm/reg/mem
CMP mem,imm/reg ;mem-imm/reg
  • 根据标志状态获知两个操作数的大小关系
  • 给条件转移等指令使用其形成的状态标志

2.测试指令TEST

进行逻辑与运算,用于判断某位为0或为1等

按位进行逻辑与运算,不返回逻辑与结果

TEST reg,imm/reg/mem ;reg ^ imm/reg/mem
TEST mem,imm/reg ;mem ^ imm/reg
  • TEST指令像AND指令一样来设置状态标志
  • 常用于检测一些条件是否满足,一般后跟条件转移指令,目的是利用测试条件转向不同的分支

3.其他指令(能够影响状态标志的指令)

加减运算指令、逻辑运算指令、移位指令等

循环指令

循环条件判断可以使用条件转移指 ,同时 IA-32 处理器针对个数控制的循环设计有若干条指令, 要是 LOOP 指令和 JECX 指令。

一、LOOP指令

IA-32 处理器 的循环指令是 LOOP,使用 ECX 寄存器作为计数器(在实地址存储模型 使用 CX), 每执行 LOOP, ECX-1。然后判断 ECX 是否为 0: 如果不为 0, 表示循环没有结束,则转移到指定的标号处;如果为 0, 表示循环结束,则顺序执行下一条指令。

(1)LOOP指令格式

循环指 LOOP 的格式如下:

LOOP label
  • 功能1:ECX←ECX-1(相当于 DEC ECX
  • 功能2:若ECX≠0,转移到LABEL, 否则,顺序执行(相当于 JNZ label

相当于

DEC ECX 
JNZ label 

寄存器ECX是默认的计数器,目标地址采用相对短转移

(2)LOOP指令的应用

LOOP是循环指令,用于实现减量计数的循环控制

  • 典型应用形式:
		mov ecx,num 	;设置循环的计数初值num
label: 	… 				;循环体
		loop label 		;ECX减1,未到0继续循环
						;到0循环结束,顺序执行
  • LOOP指令的循环次数
    循环初值12 2 32 − 1 2^{32}-1 23210
    循环次数12 2 32 − 1 2^{32}-1 2321 2 32 2^{32} 232

LOOP指令先减1后判断

 		mov ecx,0 		;设置循环的计数初值 
 label: 	loop label 	;ECX减1,未到0继续循环

在这里插入图片描述

二、JECXZ指令

LOOP 指令先进行 ECX 操作,然后判断 如果 ECX 等于0 时执行 LOOP 指令,则将循环 2 32 2^{32} 232次。所以,如果数组元素的个数为 0, 本程序将出错,为此,我们可以使用另一条循环指令JECXZ (实地址存储模型是 JCXZ 指令)排除 ECX 等于0 的情况。

  • JECXZ指令格式:

    JECXZ label
    

    ECX=0,转移到label,否则,顺序执行

    • 相当于:
      CMP ECX,0 
      JZ label 
      

在这里插入图片描述

以上是关于汇编语言转移指令&循环指令的主要内容,如果未能解决你的问题,请参考以下文章

指令系统-第三节2345:常用的x86汇编指令选择和循环语句的机器级表示

王爽《汇编语言》第三版 第九章 转移指令的原理

第九章 转移指令的原理 其一

汇编指令JMP是啥意思?

X86汇编5.高级指令详解

汇编语言 循环控制指令