微机原理第4章.ppt_第1页
微机原理第4章.ppt_第2页
微机原理第4章.ppt_第3页
微机原理第4章.ppt_第4页
微机原理第4章.ppt_第5页
已阅读5页,还剩526页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

4 1汇编语言基本概念4 28086 8088指令系统4 3汇编语言程序设计的基本方法4 4汇编语言程序的编辑 汇编与连接4 5程序的调试 第4章汇编语言程序设计基本方法 返回主目录 第4章汇编语言程序设计基本方法 4 1汇编语言基本概念 4 1 1汇编语言与机器语言我们已经学过高级语言 无论哪种语言 它都规定了一系列用于编写程序的语句和应该遵循的语法规则 人们根据一种语言给定的语句及其语法规则就可以写出程序 计算机则通过执行已编好的程序来完成人们要求它完成的各种复杂功能 汇编语言也一样 根据汇编语言的语句及其语法规则可以写出汇编语言程序 但汇编语言与高级语言有较大的区别 汇编语言中的语句与机器的种类和型号密切相关 在高级语言中 完成某个加法功能 我们可采用语句X A B 只要给变量A和B赋一确定值 此加法就可以实现了 在汇编语言中则不同 程序必须指出A B存放在何处 相加后的结果又存放在何处 然后才能实现这一加法运算 显然 汇编语言在通过程序告诉计算机做什么和如何做时 显得更加具体 正是这种具体 使得该语言与计算机 处理器 紧密相关 从而也要求学习和使用汇编语言的人对处理器的结构有更加深入的了解 那么 什么是机器语言 汇编语言与机器语言之间又有什么关系呢 我们说 机器语言是这样一种语言 它的每条语句就是计算机可以直接执行的一条指令 这些指令以二进制码的形式表示 例如我们要将累加器AX中加上一个常数02 其二进制码表示的指令为 000001010000001000000000 当处理器中取得了这样一组指令代码时 它将自动地完成 AX 2 AX 中的操作 不同的处理器 指令的机器码将各不相同 完成的具体功能也将各不相同 采用机器语言编写程序的一个最大好处是 程序送入计算机后 可以直接执行 但是 采用机器语言编写程序十分困难 既不易书写 也不易检查 汇编语言正是为了克服这一缺点而形成的一种与机器语言直接相关的语言 汇编语言的基本思想是采用一组字母 数字或符号来代替一条二进制码表示的指令 例如上面所述的指令可采用字符ADDAX 02来代替 它表示将累加器AX中的内容加上一个常数02 表示一条指令的这些字符常称为助记符 采用助记符写出的程序 机器是不能直接执行的 采用汇编语言编写的程序在执行前还必须将其 翻译 成机器语言 通常将采用助记符指令写成的程序 称为源程序 将它翻译成的机器语言程序称为目标程序 将汇编语言的源程序翻译成目标程序的过程称为汇编过程或简称汇编 汇编过程通常是由计算机完成的 它是通过执行一个专门完成汇编的软件 汇编程序来实现 源程序必须符合汇编程序的一系列要求或者规则 才能被正确地 翻译 我们要介绍的是IBMPC宏汇编语言 其汇编程序是IBMPC宏汇编程序MASM 汇编语言的语句有两种基本类型 即指令与伪指令 指令可由汇编程序翻译成机器语言指令 汇编语言中的指令与机器语言指令基本上是一一对应的 伪指令则不汇编成机器语言指令 仅仅在汇编过程中告诉汇编程序应如何汇编 例如告诉汇编程序已写出的汇编语言源程序有几个段 段的名称是什么 是否采用过程 汇编到某处是否需要留出存储空间 应留多大 是否要用到外部变量等 除了这两类基本语句外 在汇编语言中 还存在另一类指令称为宏指令 它是使用者利用上述基本语句自己定义的新的指令 4 1 2汇编语言中语句的组成汇编语言源程序是由一条条语句组成的 语句则由名称 操作助记符 操作数 注释四部分组成 1 名称 语句中的名称是一个标识符 可由字母 a b c z 数字 0 9 及特殊符号 组成 名称必须由字母打头 若名称中有圆点符 则圆点符又必须用作第一个字符 数字不能用作第一个字符 构成名称的字符总数可多达31个 若超过31个字符 则31个字符以后的字符无效 名称不是所有语句都必需的 但若语句带有名称 那么 在大多数情况下名称表示的是内存的某一存储单元的地址 也就是名称后面各项在内存存放的第一个存储单元的地址 包括该名称所在段的段地址和段内的偏移地址 名称与操作码之间的分隔可以是空格 也可以是冒号 当以冒号分隔时 该名称代表一个标号 当以空格分隔时 名称可能是标号 也可能是变量 关于标号与变量的使用及其区别 后面将逐步说明 2 操作助记符 或称助记符 操作助记符将指出该语句的基本操作功能 它是语句的必要部分 也就是说每条语句都必须有操作助记符 操作助记符是汇编语言中规定了明确含义的一组符号 所以不能随意使用 例如 ADD是加法指令的助记符 DB则是定义字节变量的伪指令助记符3 操作数 语句中的操作数部分 可以是数据本身 也可以是指出如何获得操作数的信息 前者可以是一个常数 也可以是代表常数的一个标识符或表达式 后者通常是以某种寻址方式给出的存放操作数的地址 如ADDAX 2中的第一个操作数部分 它指出该操作数存放在AX中 而第二个操作数部分则为参加运算的操作数本身 操作数不是每条语句所必须的 语句中可以没有操作数 也可以有1 2个操作数 若语句为伪指令可以有多个操作数 当语句中具有2个以上的操作数时 操作数之间应用逗号 分隔 操作数与操作助记符之间必须以空格分隔 4 注释 注释仅用作语句或程序段的说明 它不是程序的可执行部分 汇编时不形成任何目标码 注释必须以分号 开头 它可以作为语句的一个部分 也可以作为一个单独的语句 4 1 3汇编语言中的常数与表达式1 常数 常数可以分数值常数和字符串常数两类 数值常数按其基数的不同 可以有二进制数 八进制数 十进制数 十六进制数等几种不同的表示形式 汇编语言中采用不同的后缀加以区分 B 表示二进制数 例如 10110011B D 表示十进制数 例如 179D或179 O或Q 表示八进制数 例如 263O H 表示十六进制数 例如 0B3H 例中的4个数据是以不同的基数形式表示的同一个数值 当一个数值数据后面没有后缀时 将默认为十进制数 字符串常数是由单引号 括起来的一串字符 例如 THISISASUBROUTINE 179 要指出的是 此处的 179 其值并不表示十进数179 而是1 7 9三个数字的ASCII码 即31H 37H 39H 注意 汇编语言中的数值常数的第一位必须是数字 否则汇编时将被看成是标识符 例如 十六进制数FFH应表示成0FFH 2 表达式 表达式由操作数和操作符组成 操作数可以是常数或标识符 也可以是子表达式 操作符可分为算术操作符 逻辑操作符 关系操作符 属性操作符及其它操作符等 这里主要说明前三种操作符 后面两种操作符将在介绍变量与变量定义后再作介绍 算术操作符主要有 MOD 算术运算都是双操作数运算 操作数必须为数字操作数 取模运算 MOD 是取两数相除的余数 两操作数的值必须为正整数 逻辑操作符有 AND 逻辑与 OR 逻辑或 NOT 逻辑非 XOR 逻辑异或 逻辑运算的两个操作数的值也应为数字 两数进行逻辑运算是两数的对应位分别进行相应运算 例如 11001100BAND11110000B结果为11000000B 11001100BOR11110000B结果为11111100BNOT11110000B结果为00001111B 11001100BXOR11110000B结果为00111100B 注意 逻辑操作符同时又是逻辑运算指令的操作助记符 只有当它们出现在指令的操作数部分时 才是操作符 例如 ANDAL 0CHOR0FH 其中AND是指令的操作助记符 而OR是逻辑操作符 该指令指出 将AL中的内容与第二操作数的表达式的值 即两数相或的结果 相与 相与结果存放于AL中 关系操作符有 EQ 相等 EN 不等 LT 小于 GT 大于 LE 小于或等于 GE 大于或等于 关系运算的操作数也必须为数字操作数 当关系成立时 其结果为全1 当关系不成立时 其结果为全0 汇编语言中的表达式不能构成单独语句 只能是语句的一个部分 例如 MOVAX BUF 2 ADDAL VALAND0FH JMPAGAIN 3 MOVBL VBLEVA 上述各语句中都含有表达式 表达式中的标识符可以是变量名也可以是标号 关于标号与变量的定义将在下面说明 必须指出的是 语句中表达式的求值不是在执行指令时完成的 而是在对源程序进行汇编连接时完成的 所以 语句中各表达式的值必须在汇编或连接时就是确定的 也就是说 表达式中各标识符的值在汇编或连接时就应该是确定的 4 1 4标号 变量及伪指令1 标号 标号是由标识符表示的指令的名称 用以指示对应指令的位置 地址 标号有三个属性 段地址 偏移地址和类型 标号的段地址和偏移地址属性是指该标号对应的指令所在段的段地址和段内的偏移地址 标号的类型属性有两种 即NEAR和FAR标号定义成NEAR类型 表示该标号在段内使用 而定义成FAR类型则表示该标号可以在段间使用 标号的定义方法是在指令的操作助记符前加上标识符和冒号 该标识符就是标号 例如 START PUSHDS START为一标号 它代表了指令PUSH的地址 2 变量 汇编语言与高级语言一样也可以有变量 变量的值在程序运行期间是可以改变的 1 变量定义 汇编语言中的变量是通过伪指令定义的 伪指令的格式如下 变量名DB表达式 定义字节变量变量名DW表达式 定义字变量 变量名DD表达式 定义双字变量 变量名DQ表达式 定义长字变量 变量名DT表达式 定义一个十字节变量 变量名是一个标识符 其定义方法与上面指出的语句中的名称一样 但变量名后面不能加冒号 只能用空格 变量名不是必要的 在语句中可以有 也可以没有 表达式包括以下情况 1 一个或多个常数或表达式 如4 1 1中的变量DATA1 DATA4 2 带引号的字符串 如例4 1 1中的变量DATA5 DATA6 3 一个问号 如例4 1 1中的变量DATA7 DATA8 4 重复方式 此时表达式部分的格式为重复次数DUP 表达式 如例4 1 1中的变量DATA9 DATA10 例4 1 1DADA1DB20HDATA2DW0204H 1000H DATA3DB 1 3 15 3 DATA4DD12345H DATA5DB 0123 DATA6DW AB C D DATA7DB DATA8DD DATA9DB5DUP 00 DATA10DW3DUP 图4 1中给出了例4 1 1中所定义的各变量在内存存放的具体形式 图4 1中最左边一列为内存区的地址 中间一列为对应内存单元所存放的内容 右边一列为对应的变量名 图4 1中的问号 表示该内存单元中的或者内容是不确定的 即当表达式为问号时 变量所对应的内存区没有存入新的值 而只留出了相应的存储空间 如图4 1中地址为0100 0015H 0100 0019H单元中仍保持内存中原来的内容 而没有送入确定的新值 重复方式指出表达式的值可以重复地存到变量对应的内存区 重复的次数由伪指令给出 例如变量 DATA9 是在其对应的内存单元 0100 001AH 开始重复地存放5个字节的00 而DATA10则指出在它对应的内存区重复地保留3个字的空间 伪指令的功能是在变量名所对应的地址开始的内存区依次存入表达式中的各项值 表达式中的每项值所占内存的字节数与变量的类型相对应 见图4 1 当表达式的值为字符串时 对于字节类型变量 每个变量为一个字节 每个字节内存入一个字符的ASCII码 整个字符串可以在同一个引号内给出 对于字类型变量 每个变量的值不能超过2个字符 若为两个字符时同样遵循高位存入高字节 低位存入低字节的规则 若为一个字符时 该字符的ASCII码存入低字节 高字节为00 如图4 1中的DATA6 对于双字 长字类型变量 每个变量的值也不能超过两个字符并存入两个低位字节 2 变量的属性 变量具有下列属性 1 段地址 SEG 变量所在段的段地址 2 偏移地址 OFFSET 变量所在段内的偏移地址 3 类型 TYPE 变量的类型是所定义的每个变量所占据的字节数 对于DB DW DD DQ DT定义的变量其类型分别为1 2 4 8 10 通常又将DB DW DD所定义的变量分别称为BYTE类型 WORD类型和DWORD类型变量 4 长度 LENGTH 变量定义时 一个变量名所定义的变量个数 在含有DUP操作符的变量定义中 变量名所定义的变量个数为定义格式中的重复次数 5 大小 SIZE 变量定义语句中 分配给同一变量名的所有变量的总的字节数 其值为该变量的类型与长度的乘积 SIZE LENGTH TYPE上述5个属性中 前3个属性属于每一个变量 我们称其为主属性 后两个属性则是对同一语句中同一变量名所定义的所有变量而言的 我们称其为辅助属性 例4 1 1中所定义的部分变量的各属性的值列于表4 2中 4 1 5属性操作符及表达式用来获取属性或重新定义某种属性的操作符 我们称其为属性操作符 对应这样的操作符 也有其相应的表达式 1 获取属性的操作符 标号或变量一旦定义 它们都具有相应的属性 获取属性的操作符及其表达式列于表4 3中 例如对图4 1中所定义的各变量 我们有 SEGDATA1结果为0100H OFFSETDATA1结果为0000 LENGTHDATA6结果为1 TYPEDATA6结果为2 SIZEDATA9结果为5 这些表达式与上面提到的运算表达式一样 不能构成单独的语句 只能是语句的一个成分 并且表达式的求值也是在汇编过程中完成的 例如我们可以有 MOVAX SIZEDATA9 将DATA9所占的字节数送AX MOVAX SEGDATA1 将DATA1的段地址送AX MOVBL TYPEDATA9 将DATA9的类型送BL 我们还可以有如下的变量定义 DAT1DB02HDAT2DW0F00HDAT3DW5DUP DAT4DBLENGTHDAT3DAT5DWDAT3 经汇编以后 DAT4对应的内存单元中存放的是变量DAT3的长度 即5 DAT5所对应的2个字节中存放的将是变量DAT3的偏移地址 2 PTR操作符 格式 类型PTR表达式 格式中的类型可以是 BYTE WORD DWORD NEAR和FAR 前三个类型为变量类型 后两个为标号类型 格式中的表达式可以是变量名 标号或其它地址表达式 PTR操作符的功能是用来重新定义已定义的变量或标号的类型 例如上例中的变量DAT3是字变量 若程序中需将它作为字节变量使用时 必须用PTR操作来重新定义其类型 我们可以有 MOVBYTEPTRDAT3 AL这里DAT3即为格式中的表达式 从而将DAT3重新定义为字节类型 整个语句的功能将是AL中的内容送到DAT3对应的一个字节中 要指出的是变量DAT3仅在该语句中作为字节变量使用 DAT3原来定义的字变量类型并没有修改 4 28086 8088指令系统 IBMPC XT微型计算机的微处理器采用的是8088芯片 本节将介绍8088微处理器的指令系统 指令系统是指处理器所能完成的所有指令的集合 它是在微处理器设计时就确定了的 所以 对于不同的微处理器 其指令系统中所包含的具体指令将是各不相同的 微处理器8088与8086的指令系统是完全一样 8086 8088CPU指令系统可分成下面几类 1 数据传送指令 2 算术运算指令 3 逻辑运算指令 4 移位指令 5 标志处理指令和CPU控制指令 6 转移和循环控制指令 7 调用和返回指令 8 字符串操作指令 9 输入 输出指令 本节主要介绍前5类指令 后面各类指令将结合程序设计和输入 输出时分别介绍 对于指令系统的介绍 我们重点将放在各条指令的功能和它们的使用上 关于这些指令的功能是如何实现的以及执行指令的具体操作细节将不作详细讨论 学习指令系统着重要掌握指令的基本操作功能 合法的寻址方式以及对标志位的影响 在详细介绍指令系统之前 我们将书中描述指令操作时用到的各种缩写和符号列于表4 4中 4 2 1数据传送类指令这里讨论的数据传送指令仅指CPU中的寄存器与寄存器或者寄存器与存储单元之间的数据传送 这类指令的基本格式及功能说明见表4 5 表4 5数据传送类指令的格式与功能 表中除了SAHF和POPF指令外 标志寄存器F的各位均不受影响 指令中出现两个操作数时 目的操作数在前 源操作数在后 并且目的操作数的寻址方式一定不能为立即数和段寄存器CS 1 通用传送指令 MOV 指令的功能是将源操作数SRC的一个字节或一个字传送到目的操作数DST所指单元 源操作数可以是通用寄存器 段寄存器 立即数和内存单元 目的操作数可以是通用寄存器 段寄存器和内存单元 但不能为立即数和CS 内存单元可以使用各种寻址方式寻址 当目的操作数为段寄存器时 源操作数不能为立即数 当源操作数不是立即数时 两个操作数中必须有一个是寄存器 例如 MOVAX BX 将BX中的一个字传送到AX中 MOVAL DL 将DL中的一个字节传送到AL中 MOVAX 02 将立即数02传送到AX中MOVSI BX SI BX MOVAL 4 DI 将 DI 4作为偏移地址 将该单元内容送入AL MOVAX BX 2 将寄存器BX中的内容加2后的值作为偏移地址 将该单元中的一个字节送入AL中 该单元的下一个字节送AH中 MOV BX DI DX BX DI DL BX DI 1 DH说明后面三条指令的寻址方式和传送过程 MOVAL 4 DI 指令的源操作数为寄存器相对寻址方式 或称变址寻址方式 其有效地址EA DI 4 EA即为源操作数在段内的偏移地址 指令的功能是将有效地址EA所对应的单元中的一个字节送入AL中 当 DI 0400H时 该指令执行后 AL中的内容为0AH 指令的传送过程见图4 2 a MOVAX BX 2 指令的源操作数的寻址方式也为寄存器相对寻址方式 或称基址寻址方式 其有效地址EA BX 2 当 BX 1000H时 那么 EA 1002H 指令的功能是将EA所对应单元中的一个字送入AX 由于一个字的数据在内存占据两个字节单元 所以 该指令完成的传送应为 EA AL EA 1 AH 传送过程见图4 2 b MOV BX DI DX指令的源操作数的寻址方式为寄存器方式 目的操作数的寻址方式为基址变址寻址方式 其有效地址EA BX DI 指令的功能是将DX中的16位数送入有效地址EA所指的2个字节单元中 具体过程应为 DL EA DH EA 1 传送过程见图4 2 c 当程序中采用伪指令定义了一组变量后 那么 传送指令可以有下面的形式 假设变量定义如下 DATA1DW20H 30H DATA2DB50H 60H 70H DATA3DW10HDUP 传送指令可以有 MOVAX DATA1 MOVDATA3 BX MOVAL DATA2 DI MOVDATA3 SI DX MOVCX LENGTHDATA3 MOVBX SIZEDATA3 MOVSI OFFSETDATA2 第1条指令的源操作数和第2条指令的目的操作数的寻址方式为直接寻址方式 其有效地址EA即为变量DATA1和DATA3的偏移地址 可以表示为EA OFFSETDATA1和EA OFFSETDATA3 所以第1条指令的功能是将变量DATA1对应地址单元中的一个字送入AX 故 AX 0020H 第3条指令的源操作数和第4条指令的目的操作数的寻址方式为寄存器相对寻址方式 其有效地址分别为EA DI OFFSETDATA2和EA SI OFFSETDATA3 即将变址寄存器的内容加上变量DATA1或DATA3的偏移地址 若 DI 1 SI 0 DX 103FH 那么 执行第3条指令后 AL 60H 第4条指令执行后偏移地址为DATA3的内存单元内容为3FH 下一单元的内容为10H 第5条指令采用了表达式LENGTHDATA3 即取变量DATA3的长度 由于变量定义时DATA3分配了10H个字变量空间 所以 该指令执行后 CX 10H 第6条指令取的是变量DATA3所占的字节数 所以 指令执行后 BX 20H 第7条指令用了操作符OFFSET 它是将DATA2的偏移地址送入SI 最后3条指令的寻址方式均属于立即数寻址方式 因为在汇编后 源操作数已是已知的确定数值了 指令中传送的是一个字还是一个字节 通常由操作数的类型确定 当操作数是寄存器时 那么 16位寄存器将指出该操作数为字类型 8位寄存器则指出对应的操作数为字节类型 若操作数是某种寻址方式所指出的内存单元时 那么 相应的操作数的类型有时是明确的 而有时可能是不明确的 如下面3条指令 MOVDATA3 SI 02 操作DATA3的类型MOV2 SI AL AL的类型MOV4 DI 02 非法指令上述指令中的目的操作数均为寄存器相对寻址方式所指的内存某单元 第3条指令因源操作数与目的操作数的类型均不明确 因而为非法指令 此时 必须用前面介绍的PTR操作符来指明其操作类型 格式如下 MOVBYTEPTR4 DI 02 这样就指出了指令为字节操作 此外 传送指令的两个操作数的类型必须一致 否则 指令将为非法指令 如有下面的变量说明及指令 DATA1DW05H 15H 20H DATA2DB0FH 10H 0AH DATA3DB5DUP MOVAX BL 非法指令MOVAL DATA1 非法指令MOVBX DATA3 SI 非法指令上面的3条指令均为非法指令 它们的两个操作数类型都不一致 程序中有时会需要从一个字变量中取一个字节数据 例如上面的第2条指令企图完成的功能是要将05H AL中 那么 我们也必须采用PTR操作符来重新定义变量的类型 格式如下 MOVAL BYTEPTRDATA1 对于通用传送类指令 我们应着重掌握的是进行传送的两个操作数的寻址方式及其书写格式 也就是传送数据的两个操作数的有效地址以什么方式获得 并在指令中如何表示这些寻址方式及其书写格式不仅适用于传送类指令 同样也适用于其它各类指令 通用传送指令中与寻址方式有关的内容归纳如下 1 两操作数进行数据传送的正常通路如图4 3所示 图中的箭头指出了两者之间可以进行数据传送的方向 例如存储器与寄存器AX BX CX DX DI SI SP BP之间可以双向传送 而存储器与段寄存器CS之间只能单向传送 2 寄存器间接寻址 寄存器相对寻址 基址变址寻址和基址变址相对寻址方式中所用到的寄存器不能是数据寄存器AX CX和DX 只能使用变址寄存器DI SI和基址寄存器BX BP 3 寄存器相对寻址和寄存器基址变址相对寻址方式中的位移量DISP可以是常量 也可以是变量 并且可以有多种书写格式 下面以寄存器相对寻址为例 给出几种可用的书写格式 MOVAX DISP BX MOVAX BX DISP MOVAX BX DISP MOVAX BX DISP 上述4条指令的功能是完全一样的 源操作数的有效地址均为EA BX DISP 指令中的寄存器BX也可以是其它的基址 变址寄存器 最后必须指出 按某种寻址方式计算得到的有效地址是段内的偏移地址 对于某存储单元的完整地址还应包括其段地址 段地址则在相应的段寄存器中 在第3章中已指出 数据段的段地址在DS中 所以 在执行上述指令之前 首先必须通过传送指令将段地址送入段寄存器DS中 例如可以采用下面两条传送指令 MOVAX SEGDATA1 将变量DATA1的段地址送入AX MOVDS AX 若程序中所用的数据段的段址寄存器不是DS 而是ES 那么 指令中必须用段前缀加以说明 其格式为 MOVAX ES SI 它告诉汇编程序 这条指令中要取的数据的段址在ES中 而不在DS中 汇编后形成的机器指令也增加一个前缀字节 以说明所用的段寄存器 此外 当寄存器相对寻址方式中所用寄存器为BP时 所用的段寄存器有两种可能 见下面两条指令 MOVAL DATA2 BP MOVAL 10 上面第2条指令的段址将隐含为SS 而第1条指令的段址则根据变量DATA2的段址存放在哪个段寄存器中而定 例如通常数据段的段地址在DS中 因而第1条指令的段地址不在SS中 而在DS中 关于变量所在段的段地址存放在哪个段寄存器中 可由伪指令指出 这将在4 3节中介绍 2 取有效地址指令 LEA 指令的功能是将源操作数SRC的有效地址 偏移地址 送入寄存器REG中 这里的REG不允许是段寄存器 源操作数的寻址方式不允许是立即数和寄存器方式 这是一条特殊指令 它传送的不是操作数本身 而是操作数的有效地址 为说明问题 我们比较下面两行指令执行的结果 MOVAX 10H DI LEAAX 10H DI 它是将0200H段中的偏移地址为0510H处的16位数送入AX 第二条指令执行后 AX的内容为 AX 0510H 即将源操作数的有效地址的偏移地址送入了AX 取有效地址指令也可以有下面的形式 LEADI DATA1 LEABX AGAIN 假设 DI 0500H DS 0200H 对应内存单元的内容如图4 4所示 那么 第一条指令执行后 AX的内容为 AX 00FFH 指令中的DATA1及AGAIN可以是已定义的变量 也可以是程序中的语句标号 不论是变量还是标号 它们都有段和偏移地址的属性 在该指令中 它们将取变量或标号的偏移地址送入相应的寄存器 所以 下面两条指令是完全等效的 MOVAX OFFSETDATA1 LEAAX DATA1 3 取地址指针指令 LDS LES 该指令的功能是将源操作数SRC的有效地址所对应的内存单元中的32位内容分别送入DS 或ES 和指令中所指出的寄存器REG中 同样 这里的REG不允许为段寄存器 源操作数的寻址方式不允许是立即数和寄存器方式 我们可以有下面的变量定义和指令 TABLEDB10H 20H 30H 40H 50H POINT1DD02001000H POINT2DDTABLE LDSDI POINT1 DI 1000H DS 0200HLESSI POINT2 SI OFFSETTABLE ES SEGTABLE汇编后双字变量POINT2中的32位内容是变量TABLE的32位地址 其高16位是TABLE的段地址 低16位是TABLE的偏移地址 这正是双字变量的一种重要用途 上面两条指令的源操作数的寻址方式为直接寻址方式 也可采用其它寻址方式 但不同寻址方式所指的内存单元都应是双字类型 4 标志传送指令 LAHF SAHF 许多指令的执行结果会影响标志寄存器中的某些位 同时 有些指令的执行也受标志寄存器中的某些位控制 所以 标志寄存器的内容与指令的执行有着密切的关系 两条指令只是实现标志寄存器中的低8位与寄存器AH之间的传送 LAHF是将标志寄存器中的低8位内容送入寄存器AH SAHF是将AH中的8位内容送入标志寄存器的低8位中 显然SAHF指令可以同时改变标志寄存器FLAG的低8位中的各位的值 5 数据交换指令 XCHG 该指令是完成寄存器与寄存器或寄存器与存储单元之间内容交换的 该指令要求两个操作数之一必须是寄存器 允许两个操作数都是寄存器 但不允许是段寄存器 例如 XCHGAX BX AX BX XCHGCX DI CX DI XCHGBX DATA1 第2条指令和第3条指令完成的是寄存器与内存单元的内容交换 第2条指令源操作数为寄存器间接寻址 即由DI的内容指明了要交换的内存单元的偏移地址 第3条指令的源操作数为直接寻址 DATA1是已定义的变量 DATA1的偏移地址直接指明了要交换数据的内存单元的偏移地址 6 字节转换指令 XLAT 该指令的寻址方式是隐含的 其有效地址EA BX AL 指令的功能是将EA所对应的内存单元中的一个字节送入AL中 从而实现了AL中的字节变换 该指令隐含使用BX AL 该指令可用于两种代码的转换 例如要将表4 6中的代码CODE1转换成代码CODE2 我们只要将表中的代码CODE2依次存入地址连续的内存单元中 如表4 7所示 那么 若将其首地址TABLE送入BX 将需要转换的一个CODE1的代码送入AL 执行XLAT指令后 AL中便是对应的CODE2的代码了 例如 求CODE1代码中的5所对应的CODE2代码 可以用下面的程序段 movax segTABLEmovds axmovbx offsetTABLEmoval 05xlat al 1 7 堆栈操作指令 1 堆栈 堆栈是以后进先出 LIFO 的规则存取信息的一种存储机构 在微型计算机中 堆栈通常是存储器的一部分 为了保证堆栈区的存储器能按后进先出的规则存取信息 该存储区的存取地址由一个专门的地址寄存器来管理 这个地址寄存器称为堆栈指示器或称堆栈指针 当信息存入堆栈时 堆栈指针将自动减量并将信息存入堆栈指针所指出的存储单元 当需要从堆栈中取出信息时 也将从堆栈指针所指出的存储单元中读取信息 并自动将堆栈指针增量 所以 堆栈指针始终指向堆栈中最后存入信息的那个单元 堆栈顶 在信息的存与取的过程中 栈顶是不断移动的 也称它为堆栈区的动端 而堆栈区的另端则是固定不变的 这端我们又称其为栈底 在8086 8088CPU中 SS SP为堆栈指针 若把内存中某段的偏移地址为0000 00FFH的一个存储区作为堆栈 那么堆栈指针SP的初值为0100H 1 向堆栈中存入信息 首先将SP内容减2 即 SP 00FEH 然后 将16位信息送入SP所指单元 如图4 5中所示 第 1个16位信息0102H送入了00FFH和00FEH两字节单元中 随后 SP指向00FEH单元 当栈中送入4个字以后 SP将指向00F8H 2 从堆栈中取出信息 由于当前 SP 00F8H 因此 首先取出的信息将是该单元的内容 即0708H 并且SP内容加2 使SP指向00FAH 紧接着再取的第2个信息为00FAH单元的内容0506H 同时 SP的内容将修正为00FCH 可见 堆栈的读写地址由一个堆栈指针指示后 保证了它的信息存取按后进先出的规则进行 在程序设计中 堆栈是十分有用的一种结构 后面要介绍的子程序的调用与返回都将离不开堆栈 此外 堆栈还可以用来保存程序中的某些信息 这些信息需要以后进先出的规则存取 在输入输出系统中 中断响应和返回的正确操作也必须由堆栈来保证 2 堆栈操作指令 堆栈操作指令是用来完成堆栈操作的 堆栈的主要操作是对堆栈进行信息的存取 通常将信息送入堆栈的过程称为压入操作 而从堆栈中取出信息的过程称为弹出操作 8086 8088指令系统中提供了完成这两种操作的相应指令 1 压入指令 PUSH 压入指令是将SRC或标志寄存器FLAG的内容送入堆栈 并修正堆栈指针的内容 指令的操作必须是字类型的 指令中的操作数SRC可以是通用寄存器和段寄存器 也可以是某种寻址方式所指示的内存单元 但不能是立即数 指令对标志寄存器内容没有影响 例如 PUSHAX SP SP 2 SP AL SP 1 AH PUSHDS 将段寄存器的16位内容送入堆栈 并修正SP内容PUSH SI 将内存某单元的16位内容送入堆栈 PUSHF 将标志寄存器的内容压入堆栈 其过程与上面相同 其低位送入低字节 高位送入高字节 应注意的是 压入指令不能将一个常数压入堆栈 若需要将一常数送入堆栈 必须通过寄存器来实现 例如 MOVAX 0FFFFH PUSHAX 2 弹出指令 POP 弹出指令是将SP所指出的栈顶的内容取出 并送入DST所指寄存器 内存某单元或标志寄存器FLAG 并修正SP内容 DST也必须为字类型 它可以是通用寄存器和除了CS以外的段寄存器 也可以是某种寻址方式所指的内存单元 但不能为立即数 指令POPDST对标志位不产生影响 由于SP所指的就是堆栈中最后存入信息的单元 弹出指令正是弹出该单元的内容 所以 执行POP指令时是先弹出栈顶内容 后修正SP的内容 并且SP以加2修正 若有下面的程序段 MOVSP 0100H PUSHAX PUSHBX POPAX POPBX则程序执行后 SP将仍指向0100H单元 即 SP 0100H 而寄存器AX BX的内容进行了交换 这告诉我们程序中的PUSH指令与POP指令若成对出现 那么 程序执行后 堆栈指针将保持程序执行前的内容 或者说栈顶位置保持不变 4 2 2算术运算类指令1 加法与减法指令 加法 减法指令的助记符格式及其功能说明见表 指令中参加运算的两个操作数一个称为目的操作数 DST 一个为源操作数 SRC 运算结束后 目的操作数被运算结果所代替 源操作数保持不变 此外 加 减法指令对标志寄存器的各位均有影响 必须特别注意 ADDDST SRC DST SRC DST ADCDST SRC DST SRC DST CFSUBDST SRC DST DST SRC SBBDST SRC DST DST SRC CFNEGDST DST 0 DST 指令中两操作数可以采用多种寻址方式 源操作数可以为立即数 通用寄存器和任一寻址方式所指定的内存单元 目的操作数可以为通用寄存器和任一寻址方式所指定的内存单元 但不允许是立即数 当源操作数不是立即数时 两个操作数中必须有一个是寄存器 ADDAL BL AL AL BL ADDCX 08H CX CX 8 ADDAX SI AX AX SI ADDAX BX DI AX AX BX DI SUBAL CL AL AL CL SUB BX DX BX BX DX ADCAX 0 AX AX 0 CF SBBCX DATA1 CX CX DATA1 CF上述指令中 第1条与第5条指令为8位数运算指令 其余均为16位数运算指令 无论是8位还是16位数运算 两个操作数的类型必须一致 否则为非法指令 应该注意 CF的当前值是由程序中本指令之前的指令产生的 下面我们分析两条指令的执行结果 以说明指令的功能 1 ADDAX SI 该指令为16位数加法指令 目的操作数的寻址方式为寄存器方式 源操作数的寻址方式为寄存器间接方式 其功能是将AX的内容与寄存器SI的内容所指的内存单元中的16位数相加 结果送入AX 并设置标志寄存器FLAG的各位 执行过程见图4 6 图中给出 指令执行前 AX 004AH SI 0100H 偏移地址为0100H的内存单元的内容为0CH 偏移地址为0101H的内存单元内容为02H 指令执行后的结果为 偏移地址为0100H 0101H单元的内容保持不变 标志寄存器各位的含义在第3章已作详细介绍 本节所讨论的指令对标志寄存器中DF IF TF均不产生影响 凡涉及对标志位影响时 都是对除这三位以外的其余标志位而言 通常以圆点表示本指令执行后该标志位将不发生变化 需要说明的是 CF作为进位 或借位 标志时是对无符号数而言的 而OF作为溢出标志是对带符号数而言的 不论是无符号数还是带符号数 在执行指令时的运算是完全一样的 包括对标志位的影响也没有区别 如有下面的程序段 MOVAX 0FDAAH MOVBX 0FBCEH ADDAX BX程序中指令ADD将完成0FDAAH 0FBCEH的运算 程序运行后的结果为 AX 0F978H BX 0FBCEH FLAG OFSFZFAFPFCF0 2 SBBCX DATA1 该指令为带借位的16位数减法指令 目的操作数的寻址方式为寄存器方式 源操作数的寻址方式为直接方式 其功能是CX中的16位数减去变量DATA1对应的内存单元中的16位数及标志寄存器中CF的当前值 相减后的差值送寄存器CX 并设置标志寄存器FLAG的各位 执行过程见图4 7 图中指出 指令执行前 CX 3F50H 变量DATA1在数据段内的偏移地址为0006H 对应单元中的16位数为1728H 借位标志 CF 1 指令执行后其结果为 0010100000100111 CX 15 FLAG 15OFSFZFAFPFCF0 在减法指令中 标志位CF和AF分别为最高位和第3位向高位的借位 其余各位的含义与加法指令相同 由于SBB指令是一条带借位的减法指令 因此 应注意该指令执行前借位标志的当前值 对于ADC指令有相同的情况 带进位的加 减法指令主要用于多位数的加 减运算 我们知道 在8086 8088指令系统中 加法指令只能完成两个8位数相加或两个16位数相加 如要完成32位数 4个字节 的相加 必须分两步实现 首先完成低16位数的相加 并保存所得的和与进位值 然后再完成高16位数的相加 并加上低16位数相加时可能产生的进位 这样 32位数的相加就完成了 在此基础上 可以实现更多位数的相加运算 假设操作数由变量定义的方式存入内存 并且其段地址已送入DS 偏移地址ADR1已送入寄存器DI 那么 我们有如下的程序段 49821H 127654 ADR2 MOVAX 4 DI 9821H AX ADDAX DI 9821H 7654H AX MOVADR2 AX 0E75H送ADR2对应单元 MOVAX 6 DI 0004H AX ADCAX 2 DI 0012H 0004H CF AX MOVADR2 2 AX 0017H ADR2 2同样可以利用SUB指令和SBB指令的配合来实现 在进行多位数的加减运算时 除最低字的加减采用ADD或SUB指令外 高位字的运算都应采用ADC或SBB指令 表4 8中的NEGDST指令称为取负指令 它完成的是特殊的减法操作 由于它的被减数一定为0 因此 这是一条单操作数指令 实际上它是将目的操作数的值取负 若操作数的原值为一正数 那么 执行该指令后 其值变为该数的负数的补码 而若操作数的原值为一负数 补码表示 那么 执行该指令后 其值变成了该数所对应的正数 该指令将正常影响各标志位 并且CF表示最高位产生的借位 指令中操作数的寻址方式可采用除立即数外的各种寻址方式 但不能是段寄存器 例如 NEGAX NEGBYTEPTR DI NEGWORDPTR4 BX NEGDAT1 SI 都是合法指令 第1条指令是对AX的内容求负 若AX中原值为00F2H 那么 指令执行后 AX FF0EH 它正是 00F2H的补码 同时 标志寄存器的内容也将根据指令的执行而重新设置 即 CF 1 SF 1 AF 1 PF 0 OF 0 ZF 0 上面的后三条指令是对内存单元进行求负操作 我们必须注意 其中第2和第3条指令必须用PTR操作指明其操作的类型 否则 汇编时将不知道究竟是对内存中的一个字节求负还是对一个字求负 最后一条指令的操作类型由变量DAT1的类型而定 2 比较指令 比较指令的格式为 CMPDST SRC DST SRC并设置标志位指令中两操作数的寻址方式与加 减法指令的寻址方式相同 指令的功能是目的操作数减去源操作数 并根据相减结果置各标志位 它与减法指令不同的是所产生的两数之差并不取代目的操作数 因而指令执行后 仅仅改变了标志寄存器的内容 两操作数的值保持不变 指令中两操作数的类型必须一致 比较指令可以有如下的形式 CMPAL BL CMPAL DI CMPAX CX CMPAX 06H 比较指令执行后的结果仅仅体现在标志寄存器中 它是为后面的具有判别功能的指令提供条件的 3 增量和减量指令 增量和减量指令的助记符格式及其功能说明见表4 9 表中的两条指令均为单操作数指令 其操作数的寻址方式可采用除立即数外的各种寻址方式 但不能是段寄存器 指令的功能是对目的操作数加1或减1 指令除对进位标志CF不影响外 其余标志都受影响 我们可有下面的合法指令 INCAL AL AL 1 INCBX BX BX 1 INCWORDPTR4 BX BX 4 BX 4 1 DECCX CX CX 1 指令可以为字操作和字节操作两种 指令中还必须明确其操作类型 如上面的第3条指令必须用PTR操作符指出指令要对内存中的一个16位数加1 而不是对8位数加1 4 乘法指令与除法指令 乘法指令和除法指令的助记符格式及其功能说明见表4 10 乘除法指令分带符号运算和不带符号运算两种 带符号运算时 操作数和结果均以补码表示 结果的符号按一般的运算规则确定 乘法指令中的目的操作数的寻址方式是隐含的 一定是累加器AX或AL 源操作数的寻址方式可采用除立即数以外的各种寻址方式 但不能是段寄存器 指令是字运算还是字节运算由源操作数的类型确定 当字运算时 目的操作数为AX 相乘后的32位结果送DX AX DX中为高16位 AX中为低16位 当字节运算时 目的操作数为AL 相乘后的16位结果送AX 乘法指令执行后 标志寄存器中只有CF和OF位有意义 其它各位的值均为不确定 对于MUL指令 若相乘后的结果中高16位 字运算 或高8位 字节运算 均为0时 CF和OF被置为0 否则CF和OF被置成1 对于IMUL指令 若相乘后的结果中高16位或高8位为低16位或低8位的符号扩展时 CF和OF被置成0 否则CF和OF被置成1 所以 标志位CF和OF可用来判断相乘的结果中高位字或高位字节是否有值 为说明指令MUL和IMUL执行后的不同结果 我们给出下面的程序段 DAT1DW8004H MOVAX 05H MULDAT1 MOVAX 05H MULBYTEPTRDAT1 MOVAX 05H IMULBYTEPTRDAT1 MOVAX 05H IMULWORDPTRDAT1 我们分析上面程序段中4条乘法指令的执行结果 1 第1条乘法指令为无符号字运算 它完成的是05 8004H DX AX 其结果为 DX 0002H AX 8014H CF 1 OF 1 2 第2条乘法指令为无符号字节运算 它完成的是05 04H AX 其结果为 AX 0014H CF 0 OF 0 3 第3条乘法指令为带符号字节运算 因参加运算的两数都为正数 所以结果与第2条乘法指令相同 4 第4条乘法指令为带符号字运算 它同样完成的是05 8004H DX AX 但相乘结果为一负数 结果为 DX 0FFFDH AX 8014H CF 1 OF 1 除法指令中的目的操作数的寻址方式也是隐含的 并且一定为DX AX或AX 源操作数的寻址方式与乘法指令源操作数的寻址方式相同 同样 指令是字运算还是字节运算由源操作数的类型确定 当字运算时 目的操作数 即被除数 为32位 在DX AX中 DX中为高16位 源操作数 即除数 为16位 相除的结果商为16位 存于AX中 16位余数存于DX中 当字节运算时 目的操作数为16位 在AX中 源操作数为8位 相除的结果商为8位 存于AL中 8位余数存于AH中 除法指令执行后 标志位均无意义 即标志位的值都是不确定的 除法不允许出现除数为0和商溢出的情况 若发生这两种情况 结果没有意义 并引起中断 关于中断的概念将在第7章中介绍 5 符号扩展指令 有时会遇到两个长度不等的数进行加 减运算 此时 应将长度短的数的位数扩展 以使两数的长度一致 只有这样 才能保证参加运算的两个操作数的类型是一致的 此外 除法指令中的被除数必须放在AX或DX AX中 因此有时也需要将一个8位或16位数进行扩展 对于一个无符号数来说 这种扩展是简单的 只要将其高位补 0 就可以 但对一个带符号数来说就不一样了 扩展时高位补 0 还是补 1 取决于被扩展数的符号位 也就是 当被扩展数是正数时高位应补0 为负数时高位应补1 表4 11中的两条指令就是实现带符号数扩展功能的 它们都是单操作数指令 其寻址方式是隐含的 并且一定为AL或AX CBW将AL中的符号扩展到AH中 即将一个字节的带符号数扩展成一个字 扩展后AH中的内容与AL中的最高位 符号位 一致 指令CWD是将AX中的一个字扩展成DX AX中的一个双字 扩展后DX中的内容

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论