移位指令的用法,举例说明_置位指令和复位指令

移位指令的用法,举例说明_置位指令和复位指令jmp指令jmp为无条件指令,可以只修改IP,也可以同时修改CS和IP.jmp指令要给出两种信息:1) 转移的目的地址2) 转移的距离(段音转移、段内转移、段内近转移)不同的给出目的地址方法,和不同的转移位置,对应有不同格式的jmp指令.1

jmp指令   jmp为无条件指令,可以只修改IP,也可以同时修改CS和IP.   jmp指令要给出两种信息:1) 转移的目的地址2) 转移的距离(段音转移、段内转移、段内近转移)   不同的给出目的地址方法,和不同的转移位置,对应有不同格式的jmp指令.   1 依据位移进行转移的jmp指令   jmp short 标号(转到标号处执行指令)   这种格式的jmp指令实现的是段内短转移,它对IP的修改范围为-128~127,也就是说,它向前转移时可以最多超过128个字节,向后转移可以最多超过127字节. jmp指令中的”short”符号,说明指令进行的短转移. jmp指令中的”标号”是代码段中的标号,指明了指令要转移的目的地址,转移指令结束后,CS:IP应该指向标号处的指令.   程序1:   上面的程序执行后,ax中的值为1,因为执行jmp short s后,跳过了add ax, 1, IP指向标号s处的inc ax. 也就是说,程序只进行了一次ax加1操作.   汇编指令 jmp short 对应的机器指令应该是什么样的呢?我们先看一下别的汇编指令和其对应的机器指令.   可以看到,在一般的汇编指令中,汇编指令中的idata(立即数),不论它是表示一个数据还是内存单的偏移地址,都会在对应的机器指令中出现,因为CPU执行的是机器指令,它必须要处理这些数据地址.   现在我们把程序1翻译成机器码,看到的结果如图1所示:
移位指令的用法,举例说明_置位指令和复位指令
移位指令的用法,举例说明_置位指令和复位指令图1 程序1的机器码   我们可以看到,Debug将jmp short s的s表示为inc ax指令的偏移地址8,并将jmp short表示为jmp 0008,表示转移到cs:0008处. 这好像挺合理,可当看与之对应的机器码,发现了一些问题.   jmp 0008(Debug中的表示)或jmp short s(汇编语言中的表示)所对应的机器码为EB 03,注意,这个机器码竟不包含转移的目的地址,这表明CPU在执行EB 03时,并不知道转移的目的地址. 那么,CPU根据什么进行转移呢?它怎么知道转移去哪里呢?   汇编指令jmp short s中,明明带有转移的目的地址(由标号s表示)的, 可翻译成机器指令后,怎么目的地址就没了呢?没有目的地址,CPU如何知道转移到哪里呢?   我们把程序1稍作修改,变为程序2,如下:   我们在Debug中将程序2翻译成机器码,看到的结果如图2所示:
移位指令的用法,举例说明_置位指令和复位指令
移位指令的用法,举例说明_置位指令和复位指令图2 程序2的机器码   比较程序1和程序2用Debug查看的结果,注意,两个程序中的jmp指令都要使IP指向 inc ax指令,但程序1的inc ax指令的偏移地址为8,而程序2的inc ax指令的偏移地址为000BH. 而两个程序中的jmp指令所对应的机器码都是为EB 03. 这说明CPU在执行jmp指令时不需要转移的目的地址. 也就是说,CPU不需要这个目的地址就可实现IP的修改.   CPU只能处理你提供给它的东西, jmp指令的机器码码中不包含转移的目的地址,那么,CPU如何知道将IP改为多少呢?所以,在jmp指令的机器码中,一定包含了某种信息,使得CPU可以将它当做修改IP的依据. 这种信息是什么呢?   在此之前,我们来想一下CPU执行指令的过程:   1) 从CS:IP指向的内存单读取指令,读取的指令进入到指令缓冲器;2) (IP) = (IP) + 所读取指令的长度,从而指向下一条指令;3) 执行指令. 转到1,重复这个过程.   按照这个步骤,我们对照图2来看一下,程序2的jmp short s指令的读取和过程.   1) (CS) = 076Ah, (IP) = 0006h, CS:IP指向EB 03 (jmp short s的机器码);2) 读取指令EB 03f进行指令缓冲器;3) (IP) = (IP) + 所读指令的长度= 0006h + 2 = 0008h,CS:IP指向 add ax, 00014) CPU指行指令缓冲器里的指令EB 03;5) 指令EB 03执行后,(IP) = 000Bh,CS:IP指向inc ax.   CPU在执行EB 03时,是根据什么修改IP,使其指向目标指令呢?就是根据指令码的03. 注意,要转移的目的地址是CS:000B,而CPU执行EB 03时,当前的(IP) = 0008h,如果将当前的IP值加3,使(IP) = 000Bh,CS:IP就可指向目标指令. 在转移指令EB 03中并没有告诉CPU要转移的目的地址,却告诉了CPU要转移的位移,即将当前IP向后移动3个字节. 由于,程序1、2中的jmp指令转移的位移相同,都是向后3个字节,所以它们的机器码都是EB 03.   原来如此,在”jmp short 标号”指令所对应的机器码中,并不包含转移的目的地址,而包含转移的位移. 这个位移,是编译器根据汇编指令中的”标号”计算出来的,具体计算方法如图3所示:
移位指令的用法,举例说明_置位指令和复位指令
移位指令的用法,举例说明_置位指令和复位指令图3 转移位移的计算方法   实际上,”jmp short 标号”的功能为:(IP) = (IP) + 8位位移   1) 8位位移 = 标号处的地址 – jmp指令后的第一个字节的地址;   2) short 指明此处的位移为8位位移;   3) 8位位移的范围为 -128~127,用补码表示;   4) 8位位移由编译程序在编译时算出.   还有一种和”jmp short 标号”功能相近的指令格式:jmp near ptr 标号,它实现的是段内近转移.   ”jmp near ptr 标号”的功能为:(IP) = (IP) + 16位位移.   1) 16位位移 = 标号处的地址 – jmp指令后的第一个字节的地址;   2) near ptr 指明此处的位移为16位位移,进行的是段内近转移;   3) 16位位移的范围为 -32768~32767,用补码表示;   4) 16位位移由编译程序在编译时算出.   2 转移的目的地址在指令中的jmp指令   前面的jmp指令,其对应的机器指令中并没有转移的目的地址,则是相对于当前IP的转移位移.   ”jmp far ptr 标号”实现的是段间转移,又称为远转移,功能如下:   (CS) = 标号所在段的段地址; (IP) = 标号在段中的偏移地址   far ptr指明了指令用标号的段地址和偏移地址修改CS和IP.   程序3:   在Debug中将程序3翻译成机器码,如图4所示:
移位指令的用法,举例说明_置位指令和复位指令
移位指令的用法,举例说明_置位指令和复位指令图4 程序3的机器码   如图4所示,源程序中的db 256 dup(0),被Debug解释为相应的若干个汇编指令. 这不是重点,重点是,我们要注意一下jmp far ptr s所对应的机器码:EA 0B 01 BD 0B,其中包含转移的目的地址. “0B 01 BD 0B”是目的地址在指令中的存储顺序,高地址”BD 0B”是转移的段地址:0BBDh,低地址”0B 01″是偏移地址:010Bh.   3 转移地址在寄存器中的jmp指令   指令格式:jmp 16位reg   功能:(IP) = (16位reg)   4 转移地址在内存中的jmp指令   转移地址在内存中的jmp指令有两种格式:   1) jmp word ptr 内存单地址(段内转移)   功能:从内存单地址处开始放着一个字,是转移的目的偏移地址.   内存单可用寻址方式的任一格式给出.   如下面的指令:   执行后,(IP) = 0123h.   又比如,下面的指令:   2) jmp dword ptr 内存单地址(段间地址)   功能:从内存单地址处开始存放着两个字,高地址处的字是转移的目的段地址,低地址处的字是转移的目的的偏移地址.   (CS) = (内存单地址+2)(IP) = (内存单地址)   内存单地址可用寻址方式的任一格式给出.   比如,下面的指令:   执行后,(CS) = 0, (IP) = 0123h, CS:IP指向0000:0123   又比如,下面的指令:   执行后,(CS) = 0, (IP) = 0123h, CS:IP指向0000:0123   现在,我们来看一下几个程序.   程序1:   若要使程序中的jmp指令执行后,CS:IP指向程序的第一条指令,在data段中应该定义哪些数据?   分析:   代码段中,第一条指令的IP = 0   jmp word ptr [bx+1] 属于段内转移,若jmp指令执行后,CS:IP指向程序的第一条指令,则需要保证CS不变,IP = 0,因此,只要满足内存单ds:[bx+1]的字数据为0即可.   如下:   2) 程序如下:   补全程序,使jmp指令执行后,CS:IP指向程序的第一条指令.   分析:   jmp dword ptr ds:[0] 这条指令告诉我们,跳转的下一条指令的位置:   (CS) = (ds:[2]), IP = (ds:[0])   如果要保证跳转到代码段的第一条指令,需要保证内存单ds:[2]存放的字数据为CS,内存单ds:[0]存放的字数据为0.   因此,补全完的程序如下:   3) 用Debug查看内存,结果如下:   2000:1000 BE 00 06 00 00 00 …   则此时,CPU执行指令:   CS = 0006h, IP = 00BEh

2024最新激活全家桶教程,稳定运行到2099年,请移步至置顶文章:https://sigusoft.com/99576.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。 文章由激活谷谷主-小谷整理,转载请注明出处:https://sigusoft.com/24767.html

(0)
上一篇 2024年 9月 14日 上午8:36
下一篇 2024年 9月 14日 上午8:42

相关推荐

关注微信