一些转移指令

来源:互联网 发布:手机足球软件 编辑:程序博客网 时间:2024/06/04 20:09

转移指令
# 8086cpu的转移指令分为以下几类:
* 无条件转移指令(如:jmp)
* 条件转移指令
* 循环指令(如:loop)
* 过程(相当于函数)
* 中断

 # 操作符offset在汇编语言中是由编译器处理的符号,它的功能是取得标号的偏移地址 a. 无条件转移:   # jmp为无条件转移,可以只改变IP,也可以同时修改CS和IP jmp指令要提供两条信息:    * 转移的目的地址    * 转移的距离(段间距离,段内短转移,段内近转移) //==============================段内转移====================================    1)jmp short 标号 (转到标号处执行指令)        这种格式的jmp指令实现的是段内短转移,它对IP的修改范围为-128-127,即向前转移最多                    可以越过128个字节,向后转移最多可以越过127个字节            assume cs:codesg        codesg segment         start: mov ax,0            jmp short s            add ax,1    //此处ax+1未执行,由jmp直接跳过了,所以最终ax为1            s:inc ax        codesg ends        end start        实际上,指令"jmp short 标号"的功能为ip=ip+8位位移            * 8位位移="标号"处的地址->jmp指令后的第一个字节的地址            * short指令表明此处的位移为8位位移            * 8位位移的范围为-128-127,用补码表示            * 8位位移由编译程序在编译时算出    2) jmp near ptr 标号(和jmp short 标号类似,不过是段内近转移)            指令"jmp near ptr 标号"的功能为ip=ip+16位位移            * 16位位移="标号"处的地址->jmp指令后的第一个字节的地址            * near指令表明此处的位移为16位位移            * 16位位移的范围为-32769-32768,用补码表示            * 16位位移由编译程序在编译时算出    3)jmp 16位寄存器        功能:IP=16位寄存器    4)jmp word ptr 内存单元地址        功能:从内存单元地址处开始存放一个字,是转移的目的的偏移地址 //==============================段间转移=======================================     1)jmp far ptr 标号(实现的是段间转移,又称为远转移)        功能:            * cs=标号所在段的段地址            * ip=标号所在段中的偏移地址        2)jmp dword ptr 内存单元地址        功能:从内存单元地址处开始存放两个字,高地址处的字是转移目的的段地址,低地址处是                 偏移地址

b.有条件转移

1)jcxz指令    jcxz指令为有条件转移指令,所有的有条件转移指令都是短转移,在对应的机器码中包含转移的位移      而不是目的地址。对IP的修改范围都为-128-127    指令格式: jcxz 标号           如果cx=0,则转移到标号处执行,相当于(if(cx==0) jmp short 标号)2)loop    loop为循环指令,所有的循环指令都是短转移,在对应的机器码中包含转移的位移,对ip的修改范围    为-128-127    指令格式:loop 标号         每次执行后cx=cx-1,如果cx!=0,则转移到标号处执行,与jcxz相反,相当于        if(--cx!=0)            jmp short 标号

!!!注意使用转移指令时,比如

assume cs:codesgcodesg segment        mov ax,4c00h        int 21hstart:  mov ax,0s:      nop     //什么也不做,占一个字节        nop        mov di,offset s   //di保存s标志所在的偏移地址        mov si,offset s2  //si保存s2标志所在偏移地址        mov ax,cs:[si]        mov cs:[di],ax    //将s标志处的机器码改为s2标志处的机器码,s0:     jmp short s   //跳转到标志s处s1:     mov ax,0        int 21h        mov ax,0s2:     jmp short s1        nopcodesg ends        end start

来分析一下上面程序,从代码段的start标志开始执行:

1:mov ax,02:nop3:nop4:mov di,offset s5:mov si,offset s26:mov ax,cs:[si]   7:mov cs:[di],ax  /*这里将cs:[di]处的机器码改为cs:[si]的,看一                                    下cs:[si],si是标志s2处的偏移地址,s2处指令                      为    jmp short s1                        nop                    由于转移指令不是记录偏移地址,而是转移的距离,编译器                    算出地址,所以这里机器码中保存s2到s1的距离,由于                    向上转移,所以是负的,大小为字节数,看一下debug                    */

这里写图片描述
第8步跳到标志s中(jmp short s),由于标志s处机器码已经改为s2处的机器码,所以再次跳转,注意不是跳转到s1,而是向上跳转10个字节,之所以用nop就是为了使得跳转的字节大小相同,所以应该跳转到

 mov ax,4c00h int 21h

这里写图片描述
程序结束

0 0
原创粉丝点击