汇编语言指令学习之跳转指令JMP和循环指令LOOP |
您所在的位置:网站首页 › 易语言jmp › 汇编语言指令学习之跳转指令JMP和循环指令LOOP |
在汇编指令中跳转指令分为两种,一种是无条件跳转指令,一种是有条件跳转指令。 对于前者无条件跳转指令有点类似于高级语言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 |