微机CPU的指令系统

5.1 汇编语言指令格式
  为了介绍指令系统中指令的功能,先要清楚汇编语言是如何书写指令的,这就象在学习高级语言程序设计时,要清楚高级语言语句的语义、语法及其相关规定一样。

5.1.1 指令格式
  汇编语言的指令格式如下:

    指令助忆符 [操作数1 [, 操作数2 [, 操作数3]]]   [;注释]

  指令助忆符体现该指令的功能,它对应一条二进制编码的机器指令。指令的操作数个数由该指令确定,可以没有操作数,也可以有一个、二个或三个操作数。绝大多数指令的操作数要显式的写出来,但也有指令的操作数是隐含的,不需要在指令中写出。

  当指令含有操作数,并要求在指令中显式地写出来时,则在书写时必须遵守:

    ● 指令助忆符和操作数之间要有分隔符,分隔符可以是若干个空格或TAB键;
    ● 如果指令含有多个操作数,那么,操作数之间要用逗号","分开。

  指令后面还可以书写注释内容,不过,要在注释之前书写分号";"。

5.1.2 了解指令的几个方面
  在学习汇编指令时,指令的功能无疑是我们学习和掌握的重点,但要准确、有效地运用这些指令,我们还要熟悉系统对每条指令的一些规定或约束。

  归纳起来,对指令还要掌握以下几个方面内容:

    1、要求指令操作数的寻址方式;
    2、指令对标志位的影响、标志位对指令的影响;
    3、指令的执行时间,对可完成同样功能的指令,要选用执行时间短的指令(见汇编语言从入门到精通-指令汇总)。

5.2、指令系统
  指令系统是CPU指令的集合,CPU除了具有计算功能的指令外,还有实现其它功能的指令,也有为某种特殊的应用而增设的指令。

  通常,把指令按其功能分成以下几大类:

    数据传送指令        循环指令

    标志位操作指令          转移指令

    算术运算指令        条件设置字节指令

    逻辑运算指令        字符串操作指令

    移位操作指令        ASCII-BCD码运算调整指令

    位操作指令           处理器指令   

    比较运算指令

  下面,我们逐一介绍每类指令中的指令。

5.2.1 数据传送指令
  数据传送指令又分为:传送指令、交换指令、地址传送指令、堆栈操作指令、转换指令和I/O指令等。

  除了标志位操作指令SAHF和POPF指令外,本类的其它指令都不影响标志位。

  1、传送指令MOV(Move Instruction)

  传送指令是使用最频繁的指令,它相对于高级语言里的赋值语句。指令的格式如下:

    MOV Reg/Mem, Reg/Mem/Imm

  其中:Reg—Register(寄存器),Mem—Memory(存储器),Imm—Immediate(立即数),它们可以是8位、16位或32位(特别指出其位数的除外)。在本网络课件的网页中,都将采用上述缩写,此后不再说明。

  指令的功能是把源操作数(第二操作数)的值传给目的操作数(第一操作数)。指令执行后,目的操作数的值被改变,而源操作数的值不变。在存储单元是该指令的一个操作数时,该操作数的寻址方式可以是任意一种存储单元寻址方式。

  下面列举几组正确的指令例子:

  源操作数是寄存器

    MOV CH, AL   MOV BP, SP      MOV ECX, EBX
    MOV DS, AX   MOV [BX], CH   MOV [BX+SI], AX
  源操作数是存储单元

    MOV AL, [100H]   MOV BX, ES:[DI]   MOV EDX, [BX]
    MOV BX, VARW   MOV AX, [BX+SI]   MOV CH, [BX+DI+100H]
    其中:VARW是字类型内存变量(下同)。
  源操作数是立即数

    MOV AL, 89H     MOV BX, -100H      MOV EDX, 12345678H
    MOV VARW, 200H     MOV [BX], 2345H   MOV [BX+DI], 1234H

  在汇编语言中,主要的数据传送方式如图5.1所示。虽然一条MOV指令能实现其中大多数的数据传送方式,但也存在MOV指令不能实现的传送方式。

图5.1 MOV指令数据传送示意图

  对MOV指令有以下几条具体规定,其中有些规定对其它指令也同样有效。

    1)、两个操作数的数据类型要相同,要同为8位、16位或32位;如:MOV BL, AX等是不正确的;

    2)、两个操作数不能同时为段寄存器,如:MOV ES, DS等;

    3)、代码段寄存器CS不能为目的操作数,但可作为源操作数,如:指令MOV CS, AX等不正确,但指令MOV AX, CS等是正确的;

    4)、立即数不能直接传给段寄存器,如:MOV DS, 100H等;

    5)、立即数不能作为目的操作数,如:MOV 100H, AX等;

    6)、指令指针IP,不能作为MOV指令的操作数;

    7)、两个操作数不能同时为存储单元,如:MOV VARA, VARB等,其中VARA和VARB是同数据类型的内存变量。

  对于规定2、4和7,我们可以用通用寄存器作为中转来达到最终目的。表5.1列举一个可行的解决方案,尽供参考。读者可考虑用其它办法来完成同样的功能。

表5.1 MOV指令的变通方法

功能描述

不正确的指令

可选的解决方法

把DS的值传送给ES

MOV  ES, DS

MOV  AX, DS
MOV  ES, AX

把100H传给DS

MOV  DS, 100H

MOV  AX, 100H
MOV  DS, AX

把字变量VARB的值传送给字变量VARA

MOV  VARA, VARB

MOV  AX, VARB
MOV  VARA, AX

  对于情况1:不同位数数据之间的传送问题,在80386及其以后的CPU中,增加一组新的指令——传送-填充指令,它可把位数少的源操作数传送给位数多的目的操作数,多出的部分按指令的规定进行填充。

  2、传送—填充指令(Move-and-Fill Instruction)

  传送—填充指令是把位数短的源操作数传送给位数长的目的操作数。指令格式如下:

    MOVSX/MOVZX  Reg/Mem, Reg/Mem/Imm     ;80386+

  其中:及其之后的CPU,其它类似符号含义类同,不再说明。

  指令的主要功能和限制与MOV指令类似,不同之处是:在传送时,对目的操作数的高位进行填充。根据其填充方式,又分为:符号填充和零填充。

  传送—填充指令的功能如图5.2所示。

(a). MOVSX的执行效果

(b). MOVZX的执行效果

图5.2 传送—填充指令执行过程示意图

  1、符号填充指令MOVSX(Move with Sign-Extend)

    MOVSX的填充方式是:用源操作数的符号位来填充目的操作数的高位数据位。

  2、零填充指令MOVZX(Move with Zero-Extend)

来填充目的操作数的高位数据位。

  例5.1 已知:AL=87H,指令MOVSX  CX, AL,MOVZX  DX, AL执行后,问CX和DX的值是什么?
    解:根据传送-填充指令的填充方式可知:

  指令MOVSX CX, AL执行后,(CX)=0FF87H,指令MOVZX DX,
AL执行后,(DX)=0087H。

  从上例可看出,两条指令的源操作数完全一样,但因为它们的填充方式不同,所得到的结果而就不同。

  试比较下列指令,分析它们执行结果的相同和不同之处:

    MOV AX, 87H   MOVSX AX, 87H   MOVZX AX, 87H

  3、交换指令XCHG(Exchange Instruction)

  交换指令XCHG是两个寄存器,寄存器和内存变量之间内容的交换指令,两个操作数的数据类型要相同。其指令格式如下:

    XCHG  Reg/Mem, Reg/Mem

  该指令的功能和MOV指令不同,后者是一个操作数的内容被修改,而前者是两个操作数都会发生改变。寄存器不能是段寄存器,两个操作数也不能同时为内存变量。

图5.3 XCHG指令的执行功能示意图

  例5.2 已知:AX=5678H,BX=1234H,指令XCHG  AX,
BX执行后,AX和BX的值是什么?
  解:这是两个寄存器内容进行交换,指令执行后,有:(AX)=1234H,(BX)=5678H。

  4、取有效地址指令LEA(Load Effective Address)

  指令LEA是把一个内存变量的有效地址送给指定的寄存器。其指令格式如下:

    LEA Reg, Mem

  该指令通常用来对指针或变址寄存器BX、DI或SI等置初值之用。其功能如下图所示。

图5.4 LEA指令的功能示意图

  例如:

    …

    BUFFER   DB  100 DUP(?)

    …

    LEA    BX, BUFFER     ;把字节变量BUFFER在数据段内的偏移量送给BX

    …

  问题:指令“LEA  BX BUFFER”和“MOV  BX, OFFSET BUFFER”的执行效果是一样的吗?指令“LEA BX,[BX+200]”和“MOV BX,OFFSET [BX+200]”二者都正确吗?

    1、OFFSET是将数值回送变量或标号的偏移地址值.

    2.LEA是将数值回送变量或标号的有效地址值.

    3.SEG, 汇编程序将回送变量或标号的段地址值.

    4、LEA  BX,LIST5、MOV  BX,OFFSET  LIST6、可以看出,LEA和OFFSET这两条指令在功能上是相同的,BX寄存器都可得到符号地址LIST的值,而且此时MOV指令的执行速度会比LEA指令更快。但是,OFFSET只能与简单的符号地址相连,而不能和诸如LIST[SI]或[SI]等复杂操作数相连。因此,LEA指令在取得访问变量的工具方面是很有用的。

  5、取段寄存器指令(Load Segment Instruction)

  该组指令的功能是把内存单元的一个“低字”传送给指令中指定的16位寄存器,把随后的一个“高字”传给相应的段寄存器(DS、ES、FS、GS和SS)。其指令格式如下:

    LDS/LES/LFS/LGS/LSS Reg, Mem

  指令及其以后CPU中才有的指令。

  若Reg是16位寄存器,那么,Men必须是32位指针;若Reg是32位寄存器,那么,Men必须是48位指针,其低32位给指令中指定的寄存器,高16位给指令中的段寄存器。指令的执行结果如图5.5所示。

(a) 32位指针

(b) 48位指针

图5.5、LDS指令的执行步骤示意图

  例如:

    …

    POINTER   DD 12345678H

    …

    LDS    BX, POINTER

    …

  指令的执行结果如图5.5所示。各寄存器的内容分别为:(BX)=5678H,(DS)=1234H。
  下面控件是学习和掌握MOVMOVSX/MOVZXXCHGLEA、LDS/LES/LFS/LGS/LSS指令的,它可检查用户输入这些指令的合法性,并对合法的指令显示其执行的结果。

  注意:如果指令中含有表示内存单元的寻址方式,那么其控件中的"内存单元的类型"即表示该指令中内存单元的数据类型。

  6、堆栈操作指令(Stack Operation Instruction)

  堆栈是一个重要的数据结构,它具有“先进后出”的特点,通常用来保存程序的返回地址。它主要有两大类操作:进栈操作和出栈操作。

  1)、进栈操作

  a、PUSH(Push Word or Doubleword onto Stack)

    指令格式: PUSH Reg/Mem
          PUSH Imm          ;80286+

      • 一个字进栈,系统自动完成两步操作:SP←SP-2,(SP)←操作数;

      • 一个双字进栈,系统自动完成两步操作:ESP←ESP-4,(ESP)←操作数。

  b、PUSHA(Push All General Registers)

    指令格式:PUSHA       ;80286+

    其功能是依次把寄存器AX、CX、DX、BX、SP、BP、SI和DI等压栈。

  c、PUSHAD(Push All 32-bit General
Registers)

    指令格式:PUSHAD       ;80386+

    其功能是把寄存器EAX、ECX、EDX、EBX、ESP、EBP、ESI和EDI等压栈。

  2)、出栈操作

  a、POP(Pop Word or Doubleword off Stack)

    指令格式:POP Reg/Mem

      • 弹出一个字,系统自动完成两步操作:操作数←(SP),SP←SP-2;

      • 弹出一个双字,系统自动完成两步操作:操作数←(ESP),ESP←ESP-4。

  b、POPA(Pop All General Registers)

    指令格式:POPA       ;80286+

    其功能是依次把寄存器DI、SI、BP、SP、BX、DX、CX和AX等弹出栈。其实,程序员不用记住它们的具体顺序,只要与指令PUSHA对称使用就可以了。

  c、POPAD(Pop All 32-bit General Registers)

    指令格式:POPAD      ;80386+

    其功能是依次把寄存器EDI、ESI、EBP、ESP、EBX、EDX、ECX和EAX等弹出栈,它与PUSHAD对称使用即可。

  7、转换指令XLAT(Translate Instruction)

    转换指令有两个隐含操作数BX和AL。指令格式如下:

      XLAT/XLATB

    其功能是把BX的值作为内存字节数组首地址、下标为AL的数组元素的值传送给AL。其功能描述的表达式是:AL←BX[AL],其功能示意图如图5.6所示。

图5.6 XLAT/XLATB指令的功能示意图

  8、I/O指令

    有关I/O指令将在第8.1.2节——I/O指令——中介绍,在此从略。

汇编语言从入门到精通-5微机CPU的指令系统1的更多相关文章

  1. 汇编语言从入门到精通-5微机CPU的指令系统2

    微机CPU的指令系统 5.2.2 标志位操作指令 标志位操作指令是一组对标志位置位.复位.保存和恢复等操作的指令. 1.进位CF操作指令 a.清进位指令CLC(Clear Carry Flag):CF ...

  2. 汇编语言从入门到精通-2CPU资源和存储器

    CPU资源和存储器 在汇编语言中,需要访问的硬件资源主要有:CPU内部资源.存储器和I/O端口.本章将着重讲解CPU内部寄存器的命名.功能及其常见的用途,还要介绍存储器的分段管理模式.存储单元地址的表 ...

  3. 汇编语言--微机CPU的指令系统(五)(数据传送指令)

    五.微机CPU的指令系统 1.汇编语言指令格式 汇编语言的指令格式如下: 指令助忆符 [操作数1 [, 操作数2 [, 操作数3]]] [;注释] 指令助忆符体现该指令的功能,它对应一条二进制编码的机 ...

  4. 汇编语言--微机CPU的指令系统(五)(比较运算指令)

    (7)比较运算指令 在程序中,我们要时常根据某个变量或表达式的取值去执行不同指令,从而使程序表现出有不同的功能.为了配合这样的操作,在CPU的指令系统中提供了各种不同的比较指令.通过这些比较指令的执行 ...

  5. 汇编语言--微机CPU的指令系统(五)(转移指令)

    (9)转移指令 转移指令是汇编语言程序员经常使用的一组指令.在高级语言中,时常有“尽量不要使用转移语句”的劝告,但如果在汇编语言的程序中也尽量不用转移语句,那么该程序要么无法编写,要么没有多少功能,所 ...

  6. 汇编语言--微机CPU的指令系统(五)(算术运算指令)

    (3)算术运算指令 算术运算指令是反映CPU计算能力的一组指令,也是编程时经常使用的一组指令.它包括:加.减.乘.除及其相关的辅助指令. 该组指令的操作数可以是8位.16位和32位(80386+).当 ...

  7. 汇编语言--微机CPU的指令系统(五)(条件设置字节指令)

    (10)条件设置字节指令 条件设置字节指令(Set Byte Conditionally)是80386及其以后CPU所具有的一组指令.它们在测试条件方面与条件转移是一致的,但在功能方面,它们不是转移, ...

  8. 汇编语言--微机CPU的指令系统(五)(循环指令)

    (8)循环指令 循环结构是程序的三大结构之一.为了方便构成循环结构,汇编语言提供了多种循环指令,这些循环指令的循环次数都是保存在计数器CX或ECX中.除了CX或ECX可以决定循环是否结束外,有的循环指 ...

  9. 汇编语言--微机CPU的指令系统(五)(移位操作指令)

    (5) 移位操作指令 移位操作指令是一组经常使用的指令,它包括算术移位.逻辑移位.双精度移位.循环移位和带进位的循环移位等五大类. 移位指令都有指定移动二进制位数的操作数,该操作数可以是立即数或CL的 ...

随机推荐

  1. Linux tasklet 和workqueue学习

    中断服务程序一般都是在中断请求关闭的条件下执行的,以避免嵌套而使中断控制复杂化.但是,中断是一个随机事件,它随时会到来,如果关中断的时间太长,CPU就不能及时响应其他的中断请求,从而造成中断的丢失.因 ...

  2. ElementUI+Vue在使用el-dialog时,如何做到在弹出dialog时,外部呈锁定状态,而不是点击外部导致dialog直接关闭。

    ElementUI+Vue在使用el-dialog时,如何做到在弹出dialog时,外部呈锁定状态,而不是点击外部导致dialog直接关闭. 问题描述 今天,在做Element+Vue项目时发现:Di ...

  3. springBoot日志快速上手简单配置

    默认配置 日志级别从低到高分为: TRACE < DEBUG < INFO < WARN < ERROR < FATAL. 如果设置为 INFO ,则低于 INFO 的信 ...

  4. Linux创建连接命令 ln -s创建软连接

    ln -s 是linux中一个非常重要命令,一定要熟悉.它的功能是为某一个文件在另外一个位置建立一个同不的链接,这个命令最常用的参数是-s, 具体用法是:ln -s 源文件 目标文件. 当 我们需要在 ...

  5. 2、基本方法(Basic Recipes)

    学习目录:树莓派学习之路-GPIO Zero 官网地址:http://gpiozero.readthedocs.io/en/stable/recipes.html 环境:UbuntuMeta-16.0 ...

  6. emoji web端处理

    1.发送给服务器端的信息,因为图片是选择的在web端只提供了50个表情选择,所以将 #哈哈# ,凡是#  #包裹的内容转化成对应的unicode编码, 比如U+1F603.每一个对应起来,这一点比较麻 ...

  7. Python:json 模块

    字符串转dict.list data = "[{....},{...},...]" list_data = json.loads(data) dict.list转字符串 list ...

  8. Spring Boot Ftp Client 客户端示例支持断点续传

    本章介绍 Spring Boot 整合 Ftpclient 的示例,支持断点续传 本项目源码下载 1 新建 Spring Boot Maven 示例工程项目 注意:是用来 IDEA 开发工具 File ...

  9. 吴裕雄--天生自然Numpy库学习笔记:NumPy 广播(Broadcast)

    广播(Broadcast)是 numpy 对不同形状(shape)的数组进行数值计算的方式, 对数组的算术运算通常在相应的元素上进行. 如果两个数组 a 和 b 形状相同,即满足 a.shape == ...

  10. C语言-define 与do{}while(0)

    问题引出: 我们都知道宏定义#define只是简单替换,所以遇到复杂的带参数宏,必须很小心的为需要的参数加上括号“()”:同样碰到复杂的多条语句替代,虽然加{}可以将其封装成一个整体,但同时又有另一个 ...