汇编语言随笔(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 segment

strart: mov ax,0
		mov bx,0
		jmp short s
		add ax,1
	  s:inc ax
	  
codesg 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),来实现远转移。

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值