8086汇编语言程序设计(二)

 各种机器的汇编语言,其语法规则不尽相同,但基本语法结构形式类似。现以8086/8088汇编语言为例加以具体讨论。
  4.2.1 汇编语言的数据与表达式

  1.汇编语言的数据
  数据是汇编语言中操作数的基本组成成分,汇编语言能识别的数据有常数、变量和标号。
  (1)常数
  常数是指那些在汇编过程中已经有确定数值的量,它主要用作指令语句中的立即操作数、变址寻址和基址加变址中的位移量DISP或在伪指令语句中用于给变量赋初值。
  常数可以分数值常数和字符串常数两类。
  数值常数:以各种进位制数值形式表示,以后缀字符区分各种进位制,后缀字符H表示十六进制,O或Q表示八进制,B表示二进制,D表示十进制,十进制常省略后缀。
  字符串常数:用单引号括起来的一串ASⅡC码字符。如字符串"ABC"等效为41H、42H、43H一组数值常数,如"179"等效为31H、37H、39H一组数值常数。
  变量是代表存放在某些存储单元的数据,这些数据在程序运行期间可以随时修改。变量是通过变量名在程序中引用的,变量名在是存放数据存储单元的符号地址,它可以作为指令中的存储器操作数来引用。
  (2)变量
  变量一般都在数据段或附加段中使用数据定义伪指令DB、DW和DD来进行定义。定义变量就是给变量分配存储单元,且对这个存储单元赋予一个符号名――变量名,同时将这些存储单元预置初值。经过定义的变量具有以下3个属性:
  ①段属性:表示与该变量相对应的存储单元所在段的段基值;
  ②偏移量属性:表示该变量相对应的存储单元与段起始地址相距的字节数;
  ③类型属性:表示变量占用存储单元的字节数。这一属性是由数据定义伪指令DB、DW、DD来规定的。它们可以是单字节变量(或称字节变量)、双字节变量(或称字变量)、4字节变量(或称双字变量)。
  (3)标号
  标号是某条指令所在存储单元的符号地址,它指示指令在汇编语言程序中的位置,通常,标号用来作为汇编语言源程序中转移、调用以及循环等指令的操作数,即转移的目标地址。
  标号和变量相似,也有3个属性:段、偏移量和距离,前两个属性和变量的同名属性完全相同,而标号的第三个属性"距离"可以是  NEAR(近距离)或FAR(远距离)。

  NEAR(近距离):本标号只能被标号所在段的转移和调用指令所访问(即段内转移)。
  FAR(远距离):本标号可被其他段(不是标号所在段)的转换和调用指令所访问(即段间转移)。
  标号的基本定义方法是在指令的操作助记符前加上标识符和冒号,该标识符就是我们所要定义的标号。例如:
  START:PUSH DS
  标号还可以采用伪指令定义,如用LABEL伪指令和过程定义伪指令来定义,这将在后面叙述。
  2.表达式
  由常数、变量或标号和运算符连接而成的式子称为表达式,它是操作数的基本形式。表达式有数字表达式和地址表达式,汇编程序在汇编期间对表达进行计算,得到一个数值或一个地址。
  8086/8088汇编语言中的操作运算符分为:算术运算符、逻辑运算符、关系运算符、数值返回运算符、属性修改运算符。
  (1)算术运算符
  算术运算符包括加(+)、减(-)、乘(*)、除(/)和模运算符MOD。MOD施于操作,得到的是除法的余数,例如,27MOD 4,其结果为3。
  当算术运算为地址操作数时,应保证其结果是一个有意义的存储器地址,因而通常只使用+/-运算。
  (2)逻辑运算符
  逻辑运算符包括:非(NOT)、与(AND)、或(OR)和异或(XOR)。逻辑运算符的运算对象必须是数值型的操作数,并且是按位运算。应当注意逻辑运算符与逻辑运算指令之间的区别,逻辑运算符的功能是在汇编时由汇编程序完成,而逻辑运算指令的功能由CPU完成。
  (3)关系运算符
  关系运算符包括相等(EQ)、不等(NE)、小于(LT)、不大于(LE)、大于(GT)和不小于(GE)。关系运算符用于将两个操作数进行比较,若符合比较条件(即关系式成立),所得结果为全1;否则,所得结果为全0。
  (4)数值返回运算符
  数值返回运算符包括:段基值(SEG)、偏移量(OFFSET)、类型(TYPE)、长度(LENGTH)和字节总数(SIZE)。
  数值返回运算符用来把存储器操作数(变量或标号)分解为它的组成部分(段基值、偏移量、类型、元素个数总数和数据字节总数),并且返回一个表示结果的数值。这些运算符的格式如下:
  运算符 变量或标号
  ①段基值SEG运算符
  当运算符SEG加在一个变量名或标号的前面时,得到的运算结果是返回这个变量名或标号所在段的段基值。
  ②偏移量OFFSET运算符
  当运算符OFFSET加在一个变量名或标号前面时,得到的运算结果是返回这个变量或标号在它段内的偏移量。例如:
    MOV SI,OFFSET KX
  设KX在它段内的偏移量是15H,那么这个指令就等效于:
    MOV SI,15H

  这个运算符十分有用。例如,现有以ARRAY为首址的字节数组,为了逐个字节进行某种操作,可以使用下面的部分程序:
  
  在这段程序中,首先把数组变量的首字节偏移量送给SI,把寄存器SI作为数组的地址指针。这样在数组的逐个字节处理(即在LOP循环)中,用寄存器间接寻址方式,每处理完一个字节,就很方便地对地址指针SI进行修改,使它指向下一个字节。
  ③类型TYPE运算符
  运算结果是返回反映变量或标号类型的一个数值。如果是变量,则数值为字节数,DB为1,DW为2,DD为4,DQ为8,DT为10;如果是标号,则数值为代表标号类型的数值,NEAR为-1,FAR为-2。
  ④长度LENGTH运算符
  这个运算符仅加在变量的前面,返回的值是指数给变量的元素个数。如果变量是用重复数据操作符DUP说明的,则返回外层DUP给定的值;如果没有CUP说明,则返回的值总是1。
  对于数组变量,可以用重复操作表达式表达式表示,其格式为:
  重复次数DUP(操作数…操作数)
  其中,重复次数为正整数,DUP是重复操作符,括号中的操作数是重复的内容,操作数类型可以是字节、字或双字等。
  ⑤字节总数SIZE运算符
  SIZE运算符仅用于变量的前面,运算结果是返回数组变量所占的总字节数,也就是等于LENGTH和TYPE两个运算符返回值的乘积。
如数组变量ARRAY是用20HDUP(0)定义的,且数组元素的数据类型是字,则
     MOV AL,SIZE ARRAY
等效为:  MOV AL,40H

  (5)属性运算符
  属性运算符包括:类型修改(PTR)、短转移(SHORT)、类型指定(THIS)和段超越运算符(:)。这种运算符用来对变量、标号或某存储器操作数的类型属性进行修改。
  ①类型修改PTR运算符
  PTR运算符格式如下:
  类型 PTR 地址表达式
  其中,类型可以是BYTE(字节)、WORD(字)、DWORD(双字)、NEAR(近距离)、FAR(远距离)。
  运算结果是将地址表达式所指定的变量、标号或存储器操作数的类型属性,临时性地修改或指定为PTR运算中规定的类型。这种修改是临时性的,仅在有修改运算符的语句内有效。

  ②短转移SHORT运算符
  当JMP指令的目标地址与JMP指令之间的距离在-128~+127字节的范围内,可以用SHORT操作符来告诉汇编程序,将JMP指令汇编成两个字节的代码(一个字节为操作码,后一个字节为相对位移量)。例如:
    JMP SHORT NEAR_LABLE
  其中,目标标号NEAR_LABLE与JMP指令间的相对位移量在-128~+127个字节的范围内。
  ③类型指定THIS运算符
  THIS运算符的格式如下:
    THIS 类型
  其中,类型可以是BYTE、WORD、DWORD、NEAR或FAR。该操作符用来指定或补充说明变量或标号的类型。运算符THIS与LABEL伪指令有类似的效果,THIS运算符的应用举例,将在后面叙述。
  ④段超越运算符(跨段前缀)
  段超越运算符用来临时给变量、标号或地址表达式指定一个段属性。
  段超越运算符的格式为:
   段名:地址表达式
 或 段寄存器名:地址表达式
  例如:INC ES:[BP+3]
  ES:为跨段前缀,冒号":"前的ES段寄存器指明了操作数当前所在的段为附加数据段。如果没有跨段前缀"ES:",那么,由  [BP+3]地址表达式所表示的偏移地址将被系统默认为是在堆栈中。

 

3、运算符优先级(后期补充)

 

本书分为三部分。第一部分是基础部分,以8086/8088为背景,以DOS和PC兼容机为软硬件平台,以MASM和TASM为汇编器,介绍汇编语言的有关概念,讲解汇编语言程序设计技术。第部分是提高部分,以80386为背景,以新一代微处理器Pentium为目标,细致和通俗地介绍了保护方式下的有关概念,系统和详细地讲解了保护方式下的编程技术,真实和生动地展示了保护方式下的编程细节。第三部分是上机实验指导。 本书的第一部分适合初学者,可作为学习汇编语言程序设计的教材。本书的第部分适合已基本掌握8086/8088汇编语言的程序员,可作为学习保护方式编程技术的教材或参考书,也可作为其他人员了解高档微处理器和保护方式编程技术的参考书,还可作为程序员透彻地了解Windows程序设计技术的参考书。 第一部分 基础部分 第1章 绪论 1.1 汇编语言概述 1.1.1 汇编语言 1.1.2 汇编语言的特点 1.1.3 恰当地使用汇编语言 1.2 数据的表示和类型 1.2.1 数数据的表示 1.2.2 非数数据的表示 1.2.3 基本数据类型 1.3 Intel系列CPU简介 1.3.1 8位微处理器 1.3.2 16位微处理器 1.3.3 32位微处理器 1.3.4 Pentium和Pentium Pro 1.4 习题 第2章 8086/8088寻址方式和指令系统 2.1 8086/8088寄存器组 2.1.1 8086/8088 CPU寄存器组 2.1.2 标志寄存器 2.2 存储器分段和地址的形成 2.2.1 存储单元的地址和内容 2.2.2 存储器的分段 2.2.3 物理地址的形成 2.2.4 段寄存器的引用 2.3 8086/8088的寻址方式 2.3.1 立即寻址方式 2.3.2 寄存器寻址方式 2.3.3 直接寻址方式 2.3.4 寄存器间接寻址方式 2.3.5 寄存器相对寻址方式 2.3.6 基址加变址寻址方式 2.3.7 相对基址加变址寻址方式 2.4 8086/8088指令系统 2.4.1 指令集说明 2.4.2 数据传送指令 2.4.3 堆栈操作指令 2.4.4 标志操作指令 2.4.5 加减运算指令 2.4.6 乘除运算指令 2.4.7 逻辑运算和移位指令 2.4.8 转移指令 2.5 习题 第3章 汇编语言及其程序设计初步 3.1 汇编语言的语句 3.1.1 语句的种类和格式 3.1.2 数表达式 3.1.3 地址表达式 3.2 变量和标号 3.2.1 数据定义语句 3.2.2 变量和标号 3.3 常用伪指令语句和源程序组织 3.3.1 符号定义语句 3.3.2 段定义语句 3.3.3 汇编语言源程序的组织 3.4 顺序程序设计 3.4.1 顺序程序举例 3.4.2 简单查表法代码转换 3.4.3 查表法求函数 3.5 分支程序设计 3.5.1 分支程序举例 3.5.2 利用地址表实现多向分支 3.6 循环程序设计 3.6.1 循环程序举例 3.6.2 多重循环程序举例 3.7 习题 第4章 子程序设计和DOS功能调用 4.1 子程序设计 4.1.1 过程调用和返回指令 4.1.2 过程定义语句 4.1.3 子程序举例 4.1.4 子程序说明信息 4.1.5 寄存器的保护与恢复 4.2 主程序与子程序间的参数传递 4.2.1 利用寄存器传递参数 4.2.2 利用约定存储单元传递参数 4.2.3 利用堆栈传递参数 4.2.4 利用CALL后续传递参数 4.3 DOS功能调用及应用 4.3.1 DOS功能调用概述 4.3.2 基本I/O功能调用 4.3.3 应用举例 4.4 磁盘文件管理及应用 4.4.1 DOS磁盘文件管理功能调用 4.4.2 应用举例 4.5 子程序的递归和重入 4.5.1 递归子程序 4.5.2 可重入子程序 4.6 习题 第5章 输入输出与中断 5.1输 入和输出的基本概念 5.1.1 I/O端口地址和I/O指令 5.1.2 数据传送方式 5.1.3 存取RT/CMOS RAM 5.2 查询方式传送数据 5.2.1 查询传送方式 5.2.2 读实时钟 5.2.3 查询方式打印输出 5.3 中断 5.3.1 中断和中断传送方式 5.3.2 中断向量表 5.3.3 中断响应过程 5.3.4 外部中断 5.3.5 内部中断 5.3.6 中断优先级和中断嵌套 5.3.7 中断处理程序的计 5.4 基本输入输出系统BIOS 5.4.1 基本输入输出系统BIOS概述 5.4.2 键盘输入 5.4.3 显示输出 5.4.4 打印输出 5.5 软中断处理程序举例 5.5.1 打印I/O程序 5.5.2 时钟显示程序 5.6 习题 第6章 简单应用程序的计 6.1 字符串处理 6.1.1 字符串操作指令 6.1.2 重复前缀 6.1.3 字符串操作举例 6.2 十进制数算术运算调整指令及应用 6.2.1 组合BCD码的算术运算调整指令 6.2.2 未组合BCD码的算术运算调整指令 6.2.3 应用举例 6.3 DOS程序段前缀和特殊情况处理程序 6.3.1 DOS程序段前缀PSP 6.3.2 对Ctrl+C键和Ctrl+Break键的处理 6.4 TSR程序设计举例 6.4.1 驻留的时钟显示程序 6.4.2 热键激活的TSR程序 6.5 习题 第7章 高级汇编语言技术 7.1 结构和记录 7.1.1 结构 7.1.2 记录 7.2 宏 7.2.1 宏指令的定义和使用 7.2.2 宏指令的用途 7.2.3 宏指令中参数的使用 7.2.4 特殊的宏运算符 7.2.5 宏与子程序的别 7.2.6 与宏有关的伪指令 7.2.7 宏定义的嵌套 7.3 重复汇编 7.3.1 伪指令REPT 7.3.2 伪指令IRP 7.3.3 伪指令IRPC 7.4 条件汇编 7.4.1 条件汇编伪指令 7.4.2 条件汇编与宏结合 7.5 源程序的结合 7.5.1 源程序的结合 7.5.2 宏库的使用 7.6 习题 第8章 模块化程序设计技术 8.1 段的完整定义 8.1.1 完整的段定义 8.1.2 关于堆栈段的说明 8.1.3 段组的说明和使用 8.2 段的简化定义 8.2.1 存储模型说明伪指令 8.2.2 简化的段定义伪指令 8.2.3 存储模型说明伪指令的隐含动作 8.3 模块间的通信 8.3.1 伪指令PUBLIC和伪指令EXTRN 8.3.2 模块间的转移 8.3.3 模块间的信息传递 8.4 子程序库 8.4.1 子程序库 8.4.2 建立子程序库 8.4.3 使用举例 8.5 编写供Turbo C调用的函数 8.5.1 汇编格式的编译结果 8.5.2 汇编模块应该遵守的约定 8.5.3 参数传递和寄存器保护 8.5.4 举例 8.6 习题 第部分 提高部分 第9章 80386程序设计基础 9.1 80386寄存器 9.1.1 通用寄存器 9.1.2 段寄存器 9.1.3 指令指针和标志寄存器 9.2 80386存储器寻址 9.2.1 存储器寻址基本概念 9.2.2 灵活的存储器寻址方式 9.2.3 支持各种数据结构 9.3 80386指令集 9.3.1 数据传送指令 9.3.2 算术运算指令 9.3.3 逻辑运算和移位指令 9.3.4 控制转移指令 9.3.5 串操作指令 9.3.6 高级语言支持指令 9.3.7 条件字节置指令 9.3.8 位操作指令 9.3.9 处理器控制指令 9.4 实方式下的程序设计 9.4.1 说明 9.4.2 实例 9.5 习题 第10章 保护方式下的80386及其编程 10.1 保护方式简述 10.1.1 存储管理机制 10.1.2 保护机制 10.2 分段管理机制 10.2.1 段定义和虚拟地址到线性地址转换 10.2.2 存储段描述符 10 2.3 全局和局部描述符表 10.2.4 段选择子 10.2.5 段描述符高速缓冲寄存器 10.3 80386控制寄存器和系统地址寄存器 10.3.1 控制寄存器 10 3.2 系统地址寄存器 10.4 实方式与保护方式切换实例 10.4.1 演示实方式和保护方式切换的实例(实例一) 10.4.2 演示32位代码段和16位代码段切换的实例(实例) 10.5 任务状态段和控制门 10.5.1 系统段描述符 10.5.2 门描述符 10.5.3 任务状态段 10.6 控制转移 10.6.1 任务内无特权级变换的转移 10.6.2 演示任务内无特权级变换转移的实例(实例三) 10.6.3 任务内不同特权级的变换 10.6.4 演示任务内特权级变换的实例(实例四) 10.6.5 任务切换 10.6.6 演示任务切换的实例(实例五) 10.7 80386的中断和异常 10.7.1 80386的中断和异常 10.7.2 异常类型 10.7.3 中断和异常的转移方法 10.7.4 演示中断处理的实例(实例六) 10.7.5 演示异常处理的实例(实例七) 10.7.6 各种转移途径小结 10.8 操作系统类指令 10.8.1 实方式和任何特权级下可执行的指令 10.8.2 实方式及特权级0下可执行的指令 10 8.3 只能在保护方式下执行的指令 10.8.4 显示关键寄存器内容的实例(实例八) 10.8.5 特权指令 10.9 输入/输出保护 10.9.1 输入/输出保护 10.9.2 重要标志保护 10.9.3 演示输入/输出保护的实例(实例九) 10.10 分页管理机制 10.10.1 存储器分页管理机制 10.10.2 线性地址到物理地址的转换 10.10.3 页级保护和虚拟存储器支持 10.10.4 页异常 10.10.5 演示分页机制的实例(实例十) 10.11 虚拟8086方式 10.11.1 V86方式 10.11.2 进入和离开V86方式 10.11.3 演示进入和离开V86方式的实例(实例十一) 10.11.4 V86方式下的敏感指令 10.12 习题 第11章 80486及Pentium程序设计基础 11.1 80486程序设计基础 11.1.1 寄存器 11.1.2 指令系统 11.1.3 片上超高速缓存 11.2 80486对调试的支持 11 2.1 调试寄存器 11.2.2 演示调试故障/陷阶的实例 11.3 Pentium程序设计基础 11.3.1 寄存器 11.3.2 指令系统 11.3.3 处理器的识别 11.3.4 片上超高速缓存 11.4 基于Pentium的程序优化技术 11.4.1 流水线优化技术 11.4.2 分支优化技术 11.4.3 超高速缓存代化技术 11.5 习题 第三部分 上机实验指导 第12章 实验指导 12.1 实验的一般步骤 12.2 汇编器和连接器的使用 12.2.1 MASM的使用 12.2.2 LINK的使用 12.2.3 TASM的使用 12.2.4 TLINK的使用 12.3 调试器DEBUG的使用 12.3.1 启动和退出DEBUG 12.3.2 命令一览 12.3.3 利用DEBUG调试程序 12.4 Turbo Debugger的使用 12.4.1 启动和退出TD 12.4.2 利用TD调试汇编程序 参考文献 附录 Pentium指令与标志参考表
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值