汇编语言(七)—— 转移指令

转移指令

程序流程的控制转移

程序代码在代码段,CS指明代码段在主存中的段基地址,EIP给出将要执行指令的偏移地址。实现的各种指令寻址方式就是改变这两个寄存器。

  1. 指令顺序寻址,程序顺序执行,处理器自动增量EIP。
  2. 指令跳转寻址,程序控制转移,EIP(CS)随之改变(控制转移类指令:JMP, JCC, LOOP等)。
  3. 程序转移范围分为段内转移和段间转移:
    ① 段内转移:在当前代码段范围内的程序转移,不需更改CS,只要改变EIP(偏移地址)。被称为“近转移”,类型属性使用“NEAR”关键字;如果转移范围在127 ∼ \sim -128字节(位移量使用一个字节表达)之间,又称为“短转移”,类型属性使用“SHORT”关键字。
    ② 段间转移:从当前代码段跳转到另一个代码段,需要更改CS(段地址)和EIP(偏移地址)。被称为“远转移”,类型属性使用“FAR”关键字。

JMP指令

无条件转移指令:jmp dest ; dest为要跳转到的地址。

jmp label                       ; 程序转向 label 标号指定的地址
; 段内相对寻址,段间直接寻址
jmp reg32/reg16                 ; 程序转向寄存器指定的地址
; 寄存器间接寻址
jmp mem48/mem32/mem16           ; 程序转向存储单元指定的地址
; 存储器间接寻址

; e.g. 
        .data
nvar    dword ?
        .code
        jmp labl1               ; 相对寻址,短转移,位移量一个字节
        nop                     ; nop 空操作指令
labl1:  jmp near ptr labl2      ; 相对寻址,近转移,位移量四个字节
        nop
labl2:  mov eax, offset labl3
        jmp eax                 ; 跳转到 eax 的内容所指定的位置,寄存器间接寻址
        nop
labl3:  mov eax, offset labl4
        mov nvar, eax
        jmp nvar                ; 跳转到 nvar 的内容所指定的位置,存储器间接寻址
        ; jmp 指令寻址,通过存储单元间接获得下一条指令位置;
        ; 指令执行过程需要获得 nvar 变量内容,数据寻址,通过存储器的直接寻址获得数据。
        mov ebx, offset nvar
        jmp near ptr [ebx]      ; 指令的存储器间接寻址,数据的寄存器间接寻址
        nop

Jcc指令

条件转移指令:jcc dest ; cc为判断的标志条件,dest为要跳转到的地址。在满足条件时实现转移,条件不满足时顺序执行,用于实现分支、循环程序结构。

jcc label                       ; 条件满足发生转移,否则顺序执行下条指令。
; label 表示目标地址,采用段内相对寻址

判断的标志条件cc共16条指令(助记符不止16个),分成两类:
① 单个标志状态作为条件(5个状态标志ZF、CF、OF、SF、PF的10种状态);
② 两数大小关系作为条件(比较无符号整数大小:低于、不低于、低于等于、高于;比较有符号整数大小:小于、不小于、小于等于、大于)。

利用零位标志ZF的条件转移指令

根据ZF值判断运算结果为0或两数相等,针对无符号整数加减运算,实际分别为一条指令,使用多个助记符方便使用。

  1. 判断条件:运算结果为0、两数相等(ZF = 1)

     jz label            ; jump if zero
     je label            ; jump if eaual
    
  2. 判断条件:运算结果不为0、两数不相等(ZF = 0)

     jnz label            ; jump if not zero
     jne label            ; jump if not eaual
    
利用进位标志CF的条件转移指令

根据CF值判断运算结果是否有进位或借位。

  1. 判断条件:运算结果有进位或借位(CF = 1)

     jc label            ; jump if carry ,等于 jb 和 jane 指令
    
  2. 判断条件:运算结果没有进位或借位(CF = 0)

     jnc label            ; jump if not carry , 等于 jnb 和 jae 指令
    
利用溢出标志OF的条件转移指令

根据OF值判断运算结果是否有溢出,针对有符号整数加减运算。

  1. 判断条件:运算结果有溢出(OF = 1)

     jo label            ; jump if overflow 
    
  2. 判断条件:运算结果没有进位或借位(\textcolor{red}{OF = 0})

     jno label            ; jump if not overflow
    
利用符号标志SF的条件转移指令

根据SF值判断运算结果是正是负,有符号整数采用补码,最高位是符号位。符号位为1,表示负数;符号位为0,表示正数。

  1. 判断条件:运算结果有溢出(SF = 1)

     js label            ; jump if sign 
    
  2. 判断条件:运算结果没有进位或借位(SF = 0)

     jns label            ; jump if not sign
    
利用奇偶标志PF的条件转移指令

根据PF值判断低8位结果中1的个数奇偶,实际分别为一条指令,使用多个助记符方便使用。

  1. 判断条件:运算结果有溢出(PF = 1)

     jp label            ; jump if parity 
     jpe label           ; jump if parity  even
    
  2. 判断条件:运算结果没有进位或借位(PF = 0)

     jnp label           ; jump if not parity
     jpo label           ; jump if parity odd
    
两个无符号整数大小关系的条件转移指令

① 利用CF标志判断两个无符号整数的大小关系(低于、不高于等于、不低于、高于等于),本质为与jc、jnc为对应的一条指令。
② 利用CF标志和ZF标志判断两个无符号整数的大小关系(低于等于、不高于、不低于等于、高于),高(above)低(below)。

  1. 判断条件:低于、不高于等于(CF = 1) —— 减法运算有借位

     jb label            ; jump if below , 等于 jc 指令( CF = 1 ) 
     jnae label          ; jump if not above or equal , 等于 jc 指令( CF = 1 )   
    
  2. 判断条件:不低于、高于等于(CF = 0)—— 减法运算无借位

     jnb label           ; jump if not below , 等于 jnc 指令( CF = 0 ) 
     jae label           ; jump if above or equal , 等于 jnc 指令( CF = 0 ) 
    
  3. 判断条件:低于等于、不高于(CF = 1 或 ZF = 1) —— 减法运算有借位或减法运算结果为0

     jbe label           ; jump if below or equal
     jna label           ; jump if not above
    
  4. 判断条件:不低于等于、高于(CF = 0 且 ZF = 0) —— 减法运算无借位且减法运算结果不为0

     jnbe label          ; jump if not below or equal
     ja label            ; jump if above
    
两个有符号整数大小关系的条件转移指令

① 利用SF和OF标志判断两个有无符号整数的大小关系(小于、不大于等于、不小于、大于等于)。
② 利用ZF、SF和OF标志判断两个有无符号整数的大小关系(小于等于、不大于、不小于等于、大于),用大(greater)、小(less)表示。

  1. 判断条件:小于、不大于等于(SF 不等于 OF)
    当 SF = 1 ,OF = 0 时,减法运算结果为负,且无溢出,正 - 正 = 负 或 负 - 正 = 负
    当 SF = 0 ,OF = 1 时,减法运算结果为正,且有溢出,负 - 正 = 正

     jl label            ; jump if less
     jnge label          ; jump if not greater or equal
    
  2. 判断条件:不小于、大于等于(SF = OF)
    当 SF = 1 ,OF = 1 时,减法运算结果为负,且有溢出,正 - 负 = 负
    当 SF = 0 ,OF = 0 时,减法运算结果为正,且无溢出,正 - 正 = 正 或 正 - 负 = 正

     jnl label          ; jump if not less
     jge label          ; jump if greater or equal
    
  3. 判断条件:小于等于}、不大于(SF 不等于 OF 或 ZF = 1})
    当 SF = 1 ,OF = 0 时,减法运算结果为负,且无溢出,正 - 正 = 负 或 负 - 正 = 负,ZF = 1
    当 SF = 0 ,OF = 1 时,减法运算结果为正,且有溢出,负 - 正 = 正,ZF = 1

     jle label          ; jump if less or equal
     jng label          ; jump if not greater
    
  4. 判断条件:不小于等于、大于(SF = OF 且 ZF = 0)
    当 SF = 1 ,OF = 1 时,减法运算结果为负,且有溢出,正 - 负 = 负,ZF = 0
    当 SF = 0 ,OF = 0 时,减法运算结果为正,且无溢出,正 - 正 = 正 或 正 - 负 = 正,ZF = 0

     jnle label         ; jump if not less or equal 
     jg label           ; jump if greater
    

产生条件的指令

  1. 常用指令:
    ① 比较指令CMP(进行减法运算,用于判断两个数据大小或是否相等);
    ② 测试指令TEST(进行逻辑与运算,用于判断某位为0或为1等);
  2. 其他指令:能够影响状态标志的指令。① 加减运算指令;② 逻辑运算指令;③ 移位指令等。
比较指令CMP(compare)

将目的操作数减去源操作数,差值不回送目的操作数,按照减法结果影响状态标志。根据标志状态获知两个操作数的大小关系,给条件转移等指令使用其形成的状态标志。
指令:cmp dest, src ; dest为目的操作数,src为源操作数,减法不改变结果,只改变标志。

cmp reg, imm/reg/mem        ; reg - imm/reg/mem
cmp mem, imm/reg            ; mem - imm/reg
测试指令TEST

按位进行逻辑与运算,不返回逻辑结果,只修改状态标志。常用于检测一些条件是否满足,获得某些位是0是1的状态,一般后跟条件转移指令,目的是利用测试条件转向不同的分支。
指令:test dest, src ; dest为目的操作数,src为源操作数,按位逻辑与运算,不改变结果,只改变标志。

test reg, imm/reg/mem        ; reg and imm/reg/mem
test mem, imm/reg            ; mem and imm/reg

循环指令

最基本的循环指令为LOOP指令。
指令:loop dest ; dest 为目的操作数(目标地址采用相对短转移),默认计数器为ecx,实现 ecx = ecx - 1 ,如果 ecx ≠ \ne = 0 , 则转移到目标操作数;否则顺序执行。

loop label          ; ① ecx = exc - 1 , 即 dec ecx 
                    ; ② 当 ecx 不等于 0 时,转移到 label ;否则顺序执行。即 jnz label
  1. loop是循环指令,用于实现减量计数的循环控制,典型应用形式:

             mov ecx, num    ; 设置循环的计数初值 num
     label:  ...             ; 循环体
             loop label      ; ecx - 1 ,未到 0 继续循环;到 0 结束循环,顺序执行。
    
  2. loop指令的循环次数由ecx初值设置,循环初值与循环次数对应范围为 1 ∼ 2 32 − 1 1\sim2^{32}-1 12321,当设置初值为0时,循环 2 32 2^{32} 232次。

             mov ecx, 0          ; 设置循环的计数初值
     label:  loop label          ; ecx - 1 , 未到 0 继续循环
                                 ; 0 - 1 = -1 ,, 未到 0 继续循环
                                 ; -1 的 32 位补码 = FFFFFFFFH = 2^32 - 1
                                 ; 1 + 2^32 - 1 = 2^32
    
  3. JECXZ指令用于避免计数初值位0可能导致的程序错误。(指令形式:jecxz dest ; dest 为目的操作数(目标地址采用相对短转移))。

     jecxz label                 ; ecx = 0 ,转移到 label ;否则,顺序执行。
                                 ; 等价于 cmp ecx, 0 + jz label
    

参考

中国大学MOOC汇编语言程序设计

  • 3
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
一. 实验目的 1. 了解存储器的组成结构,原理和读写控制方法 2. 了解主存储器工作过程中各信号的时序关系 3. 了解挂总线的逻辑器件的特征 4. 了解和掌握总线传送的逻辑实现方法 二. 实验原理 1.基本操作:读写操作 读操作是从指定的存储单元读取信息的过程;写操作是将信息写入存储器指定的存储单元的过程 2.读写操作过程 首先要由地址总线给出地址信号,选择要进行读写操作的存储单元,然后,写操作时,先从数据总线输入要存储在该单元的数据,通过控制总线发出相应的写使能和写控制信号,这时,数据保存在该单元中;读操作时,只要通过总线发出相应的读控制信号。该数据就出现在总线上了 3. 总线传送 计算机的工作过程,实际上也就是信息的传送和处理过程,而信息的传送在计算机里面频度极高,采用总线传送必不可少,它可减少传输线路、节省器件、提高传送能力和可靠性。总线传送器件中大量使用的是三态门。三态门(ST门)主要用在应用于多个门输出共享数据总线,为避免多个门输出同时占用数据总线,这些门的使能信号(EN)中只允许有一个为有效电平(如低电平),由于三态门的输出是推拉式的低阻输出,且不需接上拉(负载)电阻,所以开关速度比OC门快,常用三态门作为输出缓冲器。其中74LS244是专用挂总线用的三态门器件之一。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值