汇编语言指令学习之跳转指令JMP和循环指令LOOP

您所在的位置:网站首页 易语言jmp 汇编语言指令学习之跳转指令JMP和循环指令LOOP

汇编语言指令学习之跳转指令JMP和循环指令LOOP

2024-07-14 16:49| 来源: 网络整理| 查看: 265

在汇编指令中跳转指令分为两种,一种是无条件跳转指令,一种是有条件跳转指令。

对于前者无条件跳转指令有点类似于高级语言C中的goto语句,goto标志符,无跳转指令的格式也是类似JMP 标号;

对于有条件跳转指令通常都是根据FLAG寄存器的相关状态值SF,OF,AF,PF,CF是否被设置为1或者是0来进行跳转的选择,这个就可以实现相关的分支语句。类似于高级语言中的if等。

(1)无条件跳转指令JMP

基本格式如下:

JMP 标号;

因为在操作系统中我们一般对程序进行分段处理,那么在不同的段就会设置不同的CS寄存器,执行不同指令的过程中实质是设置CS与IP寄存器的值,然后CPU以此来进行指令的取出,由此对于跳转指令我们就分为段内跳转和段间跳转,前者是在一个代码段中,后者是实现不同的代码段的跳转。

首先说一下段间无条件跳转。

段间的无条件跳转的实现原理是:汇编器根据JMP后面设置的标号,计算出标号对应的段内偏移与此时IP寄存器中的值得差值,然后让IP加上该差值,实质就是设置IP的值为该标号对应的段内偏移值。

根据差值所占位的大小我们又分为:无条件段内近转移和无条件段内短转移。

对于前者,偏移与IP的差值大小只占2个字节,后者占1个字节

指令格式分别如下:

无条件段内短转移:JMP SHORT 标号

无条件段内近转移:JMP NEAR PTR 标号

对于这个PTR什么时候需要添加我也不是很清楚,到后面的学习过程中明了后在进行修改。

 

对于无条件转移指令,此时的IP值是通过标号直接设置的,在汇编器解析的时候进行设置,但是有时候我们可以把需要设置的IP值放到通用寄存器或者是存储器中,那么这样就可以实现无条件段内间接跳转指令。

指令的格式如下:

JMP OPRD

其中OPRD可以是通用寄存器,也可是存储单元,寻址方式除了是立即数寻址外,可以是其它的寻址方式。

例如:

JMP AX;JMP [AX];JMP WORD PTR [1234H]等

 

(2)无条件段间跳转

所谓的无条件段间跳转就是通过相关的操作直接设置CS和IP寄存器的值,使得执行不同代码段中的代码

指令格式和上面的大同小异,但是汇编器在进行解析的时候会设置CS和IP的值。

指令分为两种:一种是直接跳转

JMP FAR PTR 标号

一种是间接跳转,通过直接寻址的方式,把存储器中的低字放到IP中,高字放到CS中,指令格式如下

JMP DWORD PTR OPRD

例如:JMP DWORD PTR [1234H],则执行后IP = DS*16+[1234H],CS = DS*16+[1236H]

 

总结了一些JMP跳转指令的相关格式:

格式

描述

举例

类别

说明

jmp 16位寄存器

以16位寄存器的值改变IP

jmp ax

段内转移

 

jmp 段地址:偏移地址

以立即数改变段地址和偏移地址

jmp 0045H:0020H

段间转移

 

jmp short 标号

以标号地址后第一个字节的地址来改变IP,实际上这个功能可以作如下描述: (IP)=(IP)+8bit位移 8bit位移指的是从jmp指令后第一个字节开始算起

jmp short sign

段内短转移

对IP的修改范围是-128->127,实际算法是编译器根据当前IP指针的指向来计算到底偏移多少个字节来指向下一条指令,下面这段代码就会出编译错误 jmp short s dw 200 dup(2) s: mov ax,4 因为跳转超过了范围

jmp near ptr 标号

以标号地址后第一个字的地址来改变IP, 实际上这个功能可以作如下描述: (IP)=(IP)+16bit位移 16bit位移指的是从jmp指令后第一个字节开始算起

jmp near ptr sign

段内近转移

对IP的修改范围是-32768->32767

jmp far ptr标号

以标号的段地址和指令地址同时改变CS和IP

jmp far ptr sign

段间转移

 

jmp word ptr 内存地址

以内存地址单元处的字修改IP,内存单元可以以任何合法的方式给出

jmp word ptr ds:[si] jmp word ptr ds:[0] jmp word ptr [bx] jmp word ptr [bp+si+idata]

段内转移

 

jmp dword ptr内存地址

以内存地址单元处的双字来修改指令,高地址内容修改CS,低地址内容修改IP,内存地址可以以任何合法的方式给出

jmp dword ptr [bx]

段间转移

s1 segment dw 0a0bh, 0c0dh s1 ends … mov ax,s1 mov ds,ax jmp dword ptr ds:[0]

对于JMP 段地址:偏移地址,并不是所有的MASM都支持的,需要依据实际的形式来判断。

 

 

上面我们看到了段内的无条件跳转指令,但是和很多高级语言进行对比,我们在很多时候都是通过条件的判断来决定是否需要进行跳转,同样在汇编指令中也提供了相关的条件跳转指令,我们现在一一进行介绍:

 

明确一下,在汇编指令中N代表的是否。同时进行条件跳转的指令都是段内跳转,因此有短和近跳转了撒!

(1)根据标识FLAG寄存器来判断是否需要进行跳转

我们根据前面的需要知道相关的算术运算、逻辑运算、移位运算(部分指令会影响CF)都会影响FLAG寄存器中的部分标识位的值,那么根据这些标志位我们可以判断是否需要进行跳转,譬如CMP AX,BX是判断AX和BX的大小,那么通过相关设置的标志位我们就可以判断是AX大还是BX大,然后决定是否需要转移嘛,这就是所谓的分支语句了撒!

对于有符号数分大于(G-great),等于(E-equal),小于(L-light)

对于无符号数分为大于(A),等于(E),小于(B)

根据标志位跳转的指令:

JE ;等于则跳转 JNE ;不等于则跳转 JZ ;为 0 则跳转 (ZF) JNZ ;不为 0 则跳转  JS ;为负则跳转 (SF) JNS ;不为负则跳转  JC ;进位则跳转 (CF) JNC ;不进位则跳转  JO ;溢出则跳转(OF) JNO ;不溢出则跳转 JA ;无符号大于则跳转  JNA ;无符号不大于则跳转  JAE ;无符号大于等于则跳转  JNAE ;无符号不大于等于则跳转  JG ;有符号大于则跳转  JNG ;有符号不大于则跳转  JGE ;有符号大于等于则跳转 JNGE ;有符号不大于等于则跳转 JB ;无符号小于则跳转  JNB ;无符号不小于则跳转 JBE ;无符号小于等于则跳转  JNBE ;无符号不小于等于则跳转  JL ;有符号小于则跳转  JNL ;有符号不小于则跳转  JLE ;有符号小于等于则跳转 JNLE ;有符号不小于等于则跳转  JP ;奇偶位置位则跳转 (PF) JNP ;奇偶位清除则跳转 JPE ;奇偶位相等则跳转  JPO ;奇偶位不等则跳转 跳转相关的标志位: 11109876543210OFDFIFTFSFZF AF PF CF溢 出   符 号零未 用辅 助未 用奇 偶未 用进 位

通过上面的跳转指令我们就可以实现简单的分支和循环,例如 MOV CX,10H

NEXT:

     ........

     DEC CX

     JNZ NEXT

实现的是执行NEXT中的代码段10次

 

但是通过自己手动的写相关的循环语句有时候很复杂,增加了编码的难度,因此在汇编指令中有了如下的专门的循环指令,如下所示:

LOOP = CX不为零的时候进行跳转

LOOPE/LOOPZ = CX不为零并且相等的时候跳转

LOOPNE/LOOPNZ = CX不为零并且不相等的时候跳转

LCXZ  CX为零的时候跳转

 

通过相关的循环+跳转语句就可以实现高级语言中的分支语句和循环语句的执行了



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3