欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

汇编语言随笔(2)-CPU指令周期和无条件转移指令(包括call和ret指令)

发布时间:2025/6/17 编程问答 67 豆豆
生活随笔 收集整理的这篇文章主要介绍了 汇编语言随笔(2)-CPU指令周期和无条件转移指令(包括call和ret指令) 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

指令周期

      在执行一条指令的过程中,由CPU完成的操作序列构成一个指令周期,通常每一个指令周期一定会包含两个子周期:即取指令子周期执行指令子周期。在取指令子周期,CPU将要执行的指令从内存中CS:IP指向的存储单元内读出(x86由PC指向内存中要执行的指令);在执行指令子周期,执行指令指定的操作。另外,将检查中断请求的操作也常作为一个子周期包含在指令周期中,即中断子周期
      1,取指子周期:它所包含的微操作一般为:对于8086cpu来说,计算出实际指令存放的物理地址,将其送上地址总线传送到内存,取得该地址上存储的指令,随后IP中的值自动增加。
      2,执行指令子周期:执行每一条指令所指定的操作。
      3,中断子周期:检查当前是否有中断请求。若有的话,8086CPU从中断信息中取得中断类型码,将标志寄存器的值入栈(pushf和popf),设置标志寄存器相关位上的值,将当前的CS:IP入栈,最后通过中断类型码将CS:IP指向相应的中断处理程序。

代码段

      之前讲过,在编程时可以根据需要将一组内存单元定义为一个段。当我们将一段代码存放在合适的内存单元中时,‘合适’指的是:代码长度不能大于64KB,必须是连续的内存单元,内存的起始地址为16的整数倍,这样就可以将其定义为一个代码段。通过设置CS:IP指向其起始地址就可以执行此代码段。

转移指令

      可以修改IP,或同时修改CS和IP的指令统称为转移指令。其中:
      只修改IP的转移行为称为段内转移,且当IP的修改范围为-128-127时,称为段内短转移;当IP的修改范围为-32768-32767时,称为段内近转移。同时修改CS和IP的转移行为称为段间转移。
      也可分为:无条件转移指令,条件转移指令,循环指令,过程和中断。

无条件转移指令(jmp)

      jmp指令一般要给出两种信息:(1)转移的目的地址(2)转移的距离(段间转移、段内短转移或段内近转移)
      1,根据相对位移进行转移的jmp指令:
      这类转移包含两种jmp转移指令,均属于段内转移。分别是段内短转移 jmp short 标号和段内近转移 jmp near ptr 标号。含义都是转移到标号处执行指令。转移位移分别用8位和16位补码来表示。
示例代码如下:

assume cs:codesg codesg segmentstrart: mov ax,0mov bx,0jmp short sadd ax,1s:inc axcodesg ends end start

在debug中的对应的机器码如下:

0BBD:0000 B80000 MOV AX,0000 0BBD:0003 B80000 MOV BX,0000 0BBD:0006 EB03 JMP 000B 0BBD:0008 050100 ADD AX,0001 0BBD:000B 40 INC AX

      其中EB03机器码中的03表示目标指令所在地址基于当前IP的相对位移。在jmp short s的执行指令子周期前,IP已经变为0008,所以在执行指令子周期中,CPU通过相对位移03计算出目标指令地址应该为0008+03,即应跳转到000B处,故设置IP值为000B,从而执行指令子周期结束。
      jmp near ptr 标号也是采用类似的方式。
      2,转移的目的地址在指令中的jmp指令
      jmp far ptr 标号,实现的是段间转移。执行效果为:用标号的段地址和偏移地址分别来修改CS和IP。
      3,转移地址在寄存器中的jmp指令
      jmp reg,效果为:将该寄存器中的值赋给IP。实现的是段内近转移。
      4,转移地址在内存中的jmp指令
      jmp word ptr 内存单元地址,效果为:在内存单元地址开始处存放着一个字,是转移的目的偏移地址(用来修改IP)。实现段内转移。
      jmp dword ptr 内存单元地址,效果为:在内存单元地址开始处存放着两个字,高地址处的是转移的目的段地址(用来修改CS),低地址处是转移的目的偏移地址(用来修改IP)。实现段间转移。

循环指令(loop)

      loop指令为循环指令,所有的循环指令都是短转移,即在其机器码中包含转移的位移,而不是目的地址。且对IP的修改范围为-128-127,采用8位补码来表示。
      loop 标号,效果为:将CX寄存器中的值减一,如果CX不为0,就跳转到标号处开始执行(jmp short 标号);若CX为0,就什么也不做,程序向下继续执行。

条件转移指令(jcxz)

      jcxz指令为有条件转移指令,所有的有条件转移指令都是短转移,即在其机器码中包含转移的位移,而不是目的地址。且对IP的修改范围为-128-127,采用8位补码来表示。
      jcxz 标号,效果为:如果CX为0,就跳转到标号处开始执行(jmp short 标号);如果CX不为0,就什么也不做,程序向下继续执行。

实现子程序设计的转移指令(call和ret)

      一:call指令
      CPU执行call指令的操作为两步:将当前的IP或CS和IP压入栈中;进行转移。
      call指令不能实现短转移,除此之外,call指令实现转移的原理和jmp指令的原理相同。简单的讲解如下:
      1,根据位移进行转移的call指令
      call 标号,效果为:将当前的IP压栈后(push IP),转到标号处执行命令(jmp near ptr 标号)。转移范围为:-32768-32767,采用16补码的段内近转移。
      下面程序执行后,IP中的值为0006。因为当call 指令执行时,IP已经为0006了(取指子周期),call执行的功能是将IP入栈并跳到标号处继续执行程序,POP AX将原IP值0006赋给ax。

0BBD:0000 B80000 MOV AX,0000 0BBD:0003 E80100 CALL S 0BBD:0006 40 INC AX 0BBD:0007 58 S: POP AX

      2,转移目的地址在指令中的call指令
      call far ptr 标号,实现段间转移。效果为:将CS入栈(push CS),将IP入栈(push IP),令CS为标号所在段的段地址,IP为标号所在段中的偏移地址,即jmp far ptr 标号。
      3,转移地址在寄存器中的call指令
      call reg,效果为:将IP入栈(push IP),令IP中的值为该寄存器中的值(jmp reg)。
      4,转移地址在内存中的call指令
      call word ptr 内存单元地址,效果为:将IP入栈(push IP),令IP中的值为内存单元地址开始处的一个字(jmp word ptr 内存单元地址)。
      call dword ptr 内存单元地址,效果为:将CS入栈(push CS),将IP入栈(push IP),在内存单元地址开始处存放着两个字,高地址处的是转移的目的段地址(用来修改CS),低地址处是转移的目的偏移地址(用来修改IP),即为jmp dword ptr 内存单元地址。
      二:ret和retf指令
      1,ret指令,效果为:用栈顶的数据来修改IP的内容(pop IP),来实现近转移。
      2,retf指令,效果为:用栈顶的数据来修改CS和IP的内容(先pop IP,后pop CS),来实现远转移。

总结

以上是生活随笔为你收集整理的汇编语言随笔(2)-CPU指令周期和无条件转移指令(包括call和ret指令)的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。