汇编基础(4) 程序控制转移
来源:互联网 发布:软件短期培训 编辑:程序博客网 时间:2024/06/05 16:30
程序控制转移
对于编程来说控制程序走向是非常重要的事情,它是你的程序根据条件
作出判断,跳转到相应的位值。
- 无条件跳转
控制程序转向的最基本的指令是jJMP.
使用形式如下:
JMP label
在程序中声明/label/的方法很简单,只要在它名字后面加上“:”,
label可以由任何字符混合而成但是不能由数字开头,例如,下面
是3个合法的label
label1:
label2:
a:
label可以在一条指令的前面声明,例如:
x1:
MOV AX, 1
x2: MOV AX, 2
下面是一个 JMP 指令的例子:
ORG 100h
MOV AX, 5 ; 将 AX 设置为 5.
MOV BX, 2 ; 将 BX 设置为 2.
JMP calc ; 跳转到 'calc'.
back: JMP stop ; 跳转到 'stop'.
calc:
ADD AX, BX ; 将 BX 加到 AX.
JMP back ; 返回 'back'.
stop:
RET ; 返回操作系统
END
当然有更简单的计算这两个数字之和的方法,但是
上面是一个JMP指令的很好的例子。
从例子中可以看出,JMP可以控制向前和向后。它可以
转移到当前代码段的任意位置(65535字节)。
短条件转移
与JMP这一无条件转移指令不同,还有一些有条件跳转
指令(只有在条件成立的时侯才跳转)。这些指令分为
三组,第一组是只检测单独标记位,第二组比较有符
号数,第三组比较无符号数。
检测单独标记位的转移指令
指令
说明
条件
相反指令
JZ , JE
如果为0(相等),转移 .
ZF =1
JNZ, JNE
JC , JB, JNAE
如果进位 (小于, 不大于等于),转移
CF = 1
JNC, JNB, JAE
JS
如果是负数,转移
SF = 1
JNS
JO
如果溢出,转移
OF = 1
JNO
JPE, JP
如果是偶数,转移
PF = 1
JPO
JNZ , JNE
如果不为0(不相等),转移
ZF = 0
JZ, JE
JNC , JNB, JAE
如果没有进位(大于, 大于等于),转移
CF = 0
JC, JB, JNAE
JNS
如果不是负数,转移
SF = 0
JS
JNO
如果没有溢出,转移
OF = 0
JO
JPO, JNP
如果不是偶数,转移
PF = 0
JPE, JP
可以看到一些指令功能相同,对,他们编译之后生成
相同机器码所以很容易理解为什么你编译 JE 指令
而反编译得到的却是JZ.使用不同的名称是为了使程序更容易理解。
比较有符号数的转移指令
指令
说明
条件
相反指令
JE , JZ
如果等于 (=),如果为0,跳转
ZF = 1
JNE, JNZ
JNE , JNZ
如果不等于 (<>),如果不等于0,跳转
ZF = 0
JE, JZ
JG , JNLE
如果大于 (>) 如果不小于等于 (not <=),跳转
ZF = 0
和
SF = OF
JNG, JLE
JL , JNGE
如果小与Jump if Less (<) 如果不大于等于 (not >=),跳转
SF <> OF
JNL, JGE
JGE , JNL
如果大于等于 (>=),如果不小于 (not <),跳转
SF = OF
JNGE, JL
JLE , JNG
如果小于等于 (<=),如果不大于 (not >),跳转
ZF = 1
或者
SF <> OF
JNLE, JG
<> - 符号表示不等于.
比较无符号数转移指令
指令
说明
条件
相反指令
JE , JZ
如果等于 (=).,如果为0,跳转
ZF = 1
JNE, JNZ
JNE , JNZ
如果不等于(<>),如果不为0,跳转
ZF = 0
JE, JZ
JA , JNBE
如果大于 (>),如果不小于等于(not <=),跳转
CF = 0
and
ZF = 0
JNA, JBE
JB , JNAE, JC
如果小于 (<),如果不大于等于(not >=),如果进位,跳转
CF = 1
JNB, JAE, JNC
JAE , JNB, JNC
如果大于等于(>=),如果不小于 (not <),如果没有进位,跳转
CF = 0
JNAE, JB
JBE , JNA
如果小于或者等于(<=),如果不大于 (not >),跳转
CF = 1
or
ZF = 1
JNBE, JA
一般来说,需要使用CMP指令来比较数值(该指令与 SUB(减法)
指令相近,只不过不保存结果,而只修改标值位)
上面说法的意思是,例如:
需要比较5 和2, 5-2 =3
结果不是0(0标值位设置为 0)
另一个例子
比较 7和7
7 - 7 = 0
结果为0! (0标值位设置为1。 JZ 或者 JE 会转移).
下面是一个 CMP 指令和条件转移指令的例子:
include emu8086.inc
include emu8086.inc
ORG 100h
MOV AL, 25 ; 设置AL为 25.
MOV BL, 10 ; 设置BL为10.
CMP AL, BL ; 比较 AL - BL.
JE equal ; 如果 AL = BL (ZF = 1) 跳转
PUTC 'N' ; 如果到这里,说明 AL <> BL,
JMP stop ; 打印'N', 跳转到结束
equal: ; 如果到这里
PUTC 'Y' ; 则 AL = BL,打印'Y'.
stop:
RET
END
请用用不同的数字试验取代上述 AL 和 BL,点击[FLAGS]键
打开标志,使用[Single Step]观察发生了什么,不要忘记
每一次修改之后重新编译运行(快捷键F5)。
全部的条件转移指令都有一个很大的限制,就是与 JMP 指令
不同,他们只能向前跳转127字节或者向后跳转128字节(注意
大多数指令编译之后是3个或者更多字节)
我们可以用如下小技巧解决这一问题:
- 从上述表中找到一条相反条件的转移指令,令其跳转到 label_x.
- 用JMP指令跳转到你想要的地方
- 在JMP指令后面定义label_x:
label_x: - 可以是任意合法标号.
下面是一个例子:
include emu8086.inc
ORG 100h
MOV AL, 25 ; 设置 AL 为 25.
MOV BL, 10 ; 设置 BL 为 10.
CMP AL, BL ; 比较 AL - BL.
JNE not_equal ; 如果 AL <> BL (ZF = 0),转移
JMP equal
not_equal:
; 假定这里还有编译之后超过127字节的程序
PUTC 'N' ; 如果执行到这里,说明 AL <> BL,
JMP stop ; 打印 'N', 转移到程序结束。
equal: ; 如果执行到这里,
PUTC 'Y' ; 说明 AL = BL, 打印 'Y'.
stop:
RET ; 上述都要执行这一条
END
另外,可以使用立即数来代替标号。立即数前使用“$”
编译器将直接得到偏移。例如:
ORG 100h
; 无条件向前转移
; 跳过后面2字节
JMP $2
a DB 3 ; 1 byte.
b DB 4 ; 1 byte.
; JCC 跳过 7 字节:
; (JMP 本身占用 2 字节)
MOV BL,9
DEC BL ; 2 bytes.
CMP BL, 0 ; 3 bytes.
JNE $-7
RET
END
- 汇编基础(4) 程序控制转移
- 程序控制
- 汇编学习--7.13--转移指令
- 汇编中的条件转移指令
- 汇编转移指令的原理
- [Intel汇编-MASM]转移指令
- 汇编转移指令jmp原理
- java基础---->数据类型、运算符、程序控制
- MATLAB基础5-MATLAB程序控制结构
- python基础系列(二)程序控制结构
- Java基础--数据类型,运算符,程序控制语句
- 【c++基础】4.程序控制结构概述
- 汇编 段内转移和段间转移
- 汇编学习--汇编基础
- 汇编基础
- 汇编基础
- 汇编基础
- 汇编基础
- Java Container Learning notes
- myeclipse6.0+tomcat6.0 数据源的配置 与tomcat5.X的区别
- 汇编基础(3) 运算与逻辑指令
- 更系统地掌握Struts1.x/Struts2.x+Hibernate+Spring框架组合,请学习SpringSide或Appfuse
- 编程技巧之:双击VC对话框提示cannot add new member以及类向导中没有已经建立的类的解决方法
- 汇编基础(4) 程序控制转移
- 在每一条错误的道路上成长
- SSH整合
- 再放QQ微博邀请码(2)
- struts1.2和spring的整合几种方式
- 新装Netbeans字体无法看清的解决办法
- EXTJS用户登录
- 堆和栈的区别
- java中的ClassLoader