第四章 80x86汇编语言程序设计 第一节 汇编语言概述 第二节 汇编语言语句的组成 第三节 汇编语言的语句 第四节 宏汇编指令 第一节 汇编语言概述 第二节 汇编语言语句的组成 第三节 汇编语言的语句 第四节 宏汇编指令 第五节 编写完整的汇编语言程序 第六节 汇编语言程序设计.

Slides:



Advertisements
Similar presentations
输入输出程序设计 输入输出的基本概念 无条件方式输入输出 查询方式输入输出 中断方式输入输出.
Advertisements

汇编语言程序设计 吴 向 军 中山大学计算机科学系
微型计算机技术 教 学 指 导(七) 太原广播电视大学 郭建勇.
第10章 DOS功能调用与BIOS中断调用.
第7章 8086/8088汇编语言程序设计 7.1 引言 7.2 顺序程序设计 7.3 分支结构程序设计 7.4 循环结构程序设计
第四章 汇编语言 程序设计 任课教师:王晓甜
本周实验安排 实验内容:(P231)人名排序的例子。
微机原理与接口技术 微机原理与接口技术 朱华贵 2015年10月30日.
IBM-PC 汇编语言程序设计 教师:袁南儿.
第3章 80x86汇编语言程序设计(下).
4.1 汇编语言 4.2 顺序结构程序 4.3 分支程序设计 4.4 循环程序设计 4.5 子程序设计
第5章 汇编语言程序设计 5.1 宏汇编语言的基本语法 5.2 伪指令 5.3 宏指令 5.4 汇编语言程序的结构
9.1 可编程并行输入/输出接口芯片8255A 9.2 可编程计数器/定时器 可编程串行输入/输出接口芯片8251A
3.3.5 程序控制指令 控制转移指令分为: 转移指令 循环控制指令 调用和返回指令 中断指令.
第四章 汇编语言程序格式 4.1 汇编语言语句种类及其格式
微机原理与接口技术 微机原理与接口技术 朱华贵 2015年11月26日.
第4章 汇编语言程序设计 4.1 汇编语言概述 4.2 汇编语言源程序格式 4.3 汇编语言程序设计 4.4 DOS功能调用.
第5章 循环与分支程序设计  循环程序设计  分支程序设计.
汇编语言程序设计 Assembly Language Programming
第三章 寻址方式与指令系统 3.1 寻址方式 一条指令通常由两大部分构成: 操作码 操作数
第九章 计数器和定时器电路 第一节 概述 第二节 Intel 8253的控制字 第三节 Intel 8253的工作方式 第九章 计数器和定时器电路 第一节 概述 第二节 Intel 8253的控制字 第三节 Intel 8253的工作方式 第四节 Intel 8253在IBM PC机上的应用.
微机原理与接口技术 微机原理与接口技术 朱华贵 2015年12月10日.
微机原理与接口技术 微机原理与接口技术 朱华贵 2015年11月05日.
第八章 输入输出程序设计 总线 CPU MEM I/O接口 I/O设备.
第4章 8086汇编语言程序设计 几个概念 8086汇编语言的语句 8086汇编中的伪指令 8086汇编中的运算符 汇编语言程序设计
第4章 汇编语言程序设计 4.1 程序设计语言概述 4.2 汇编语言的程序结构与语句格式 4.3 汇编语言的伪指令
走进编程 程序的顺序结构(二).
微机原理与接口技术 ——80x86微处理器 西安邮电大学 计算机学院 范琳.
第一章 8086程序设计 第二章 MCS-51程序设计 第三章 微机基本系统的设计 第四章 存贮器与接口 第五章 并行接口
汇编语言程序设计课程设计 第二次实验 DEBUG基本命令与算术运算指令
第一单元 初识C程序与C程序开发平台搭建 ---观其大略
微型计算机原理及应用.
第3章 微型计算机输入输出接口 3.1 输入/输出接口 3.2 输入输出数据传输的控制方式 3.3 开关量输入输出接口 欢迎辞.
第六章 子程序结构 §6.1 子程序的设计方法 §6.2 嵌套与递归子程序 §6.3 子程序举例 §6.4 DOS系统功能调用.
第 13 章 中断系统.
第二章 Java语言基础.
第九章 高级宏汇编语言 9.1 结构 结构就是将逻辑上有一定关系的一组数据,以某种方式组合在一起所形成的数据形式。
第5章 循环与分支程序设计 学习目标: 了解并掌握循环程序的构造方法,尤其是对循环控制条件的设置以及可能出现的边界情况的考虑。掌握起泡排序算法这种多重循环程序设计中的常用方法。交换标志位的设置在此算法中更能提高效率。学会在数组排序算法中采用折半查找法来提高查找效率。学会使用跳跃表法实现CASE结构。
4.1 汇编语言程序格式 4.2 MASM中的表达式 4.3 伪指令语句 4.4 DOS系统功能调用和BIOS中断调用
微机原理与接口技术 微机原理与接口技术 朱华贵 2015年11月19日.
第五章:输入输出基本技术 主讲教师:范新民.
第4章 汇编语言程序格式  汇编程序功能  伪操作  汇编语言程序格式  汇编语言程序的上机过程.
第7章 在C/C++中使用汇编 罗文坚 中国科大 计算机学院
C语言程序设计 主讲教师:陆幼利.
学习目标 1、什么是字符集 2、字符集四个级别 3、如何选择字符集.
习题3 1、 分别说明下列指令的原操作数和目的操作数各采用什么寻址方式。 设定如下: ①立即寻址 ② ① ②寄存器寻址
第九章 BIOS和DOS中断 在存储器系统中,从地址0FE000H开始的8K ROM(只读存储器)中装有BIOS(Basic Iuput /output System)例行程序。驻留在ROM中的BIOS给PC系列的不同微处理器提供了兼容的系统加电自检,引导装入,主要I/O设备的处理程序以及接口控制等功能模块来处理所有的系统中断。使用BIOS功能调用,给程序员编程带来很大方便,程序员不必了解硬件操作的具体细节,直接用指令设置参数,然后中断调用BIOS中的子功能,所以利用BIOS功能编写的程序简洁,可读性好,
第2章 80x86计算机组织  计算机系统  存储器  中央处理机  外部设备.
微机原理与接口技术 微机原理与接口技术 朱华贵 2015年11月13日.
《微型计算机原理与接口技术》 第4版 王良 宁德师范学院 吴宁 乔亚男 编著 清华大学出版社 出版
第5章 循环与分支程序设计  循环程序设计  分支程序设计.
微机原理与接口技术 微机原理与接口技术 朱华贵 2015年12月17日.
第八章 中断系统.
第九节 赋值运算符和赋值表达式.
College of Computer Science & Technology
多层循环 Private Sub Command1_Click() Dim i As Integer, j As Integer
ASP.NET实用教程 清华大学出版社 第4章 C#编程语言 教学目标 教学重点 教学过程 2019年5月5日.
微机原理与接口技术 ——8086微处理器 西安邮电大学 计算机学院 范琳.
微机原理与接口技术 微机原理与接口技术 朱华贵 2015年11月06日.
本节内容 C语言的汇编表示 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
3. 逻辑运算指令 A、简单逻辑操作指令 CLR A. (不影响CY、AC、 OV标志) CPL A
Chapter 7&8 Assembly Programming
微机原理与接口技术 西安邮电大学计算机学院 宁晓菊.
C++语言程序设计 C++语言程序设计 第一章 C++语言概述 第十一组 C++语言程序设计.
第6章 子程序结构 在程序设计中,我们会发现一些多次无规律重复的程序段或语句序列。解决此类问题一个行之有效的方法就是将它们设计成可供反复调用的独立的子程序结构,以便在需要时调用。在汇编语言中,子程序又称过程。 调用子程序的程序称为主调程序或主程序。 2019/7/20 ch6.
微机原理与接口技术 第5章 汇编语言程序设计 西安邮电大学计算机学院 王 钰.
第4章 汇编语言程序格式  汇编程序功能  伪操作  汇编语言程序格式  汇编语言程序的上机过程
第三章 8086的指令系统 8086指令特点 8086的寻址方式 8086的指令格式及数据类型 8086的指令集.
顺序结构程序设计 ——关于“字符串”和数值.
跟我一起学编程系列课程: 第一篇汇编语言 16位汇编.
Presentation transcript:

第四章 80x86汇编语言程序设计 第一节 汇编语言概述 第二节 汇编语言语句的组成 第三节 汇编语言的语句 第四节 宏汇编指令 第一节 汇编语言概述 第二节 汇编语言语句的组成 第三节 汇编语言的语句 第四节 宏汇编指令 第五节 编写完整的汇编语言程序 第六节 汇编语言程序设计

助记符——用便于记忆的英语单词表示的指令操作码。它反映了指令的功能和主要特征,便于人们理解和记忆。 第一节 汇编语言概述 机器语言——二进制数形式的指令和数据。 B0 64 是什么意思?这就是机器语言。既不直观,又不易理解和记忆. MOV AL,64H ;很容易记忆理解,这就是助记符。 助记符——用便于记忆的英语单词表示的指令操作码。它反映了指令的功能和主要特征,便于人们理解和记忆。

汇编语言——指令助记符,符号地址,标号,伪指令等语言元素的集合以及这些元素使用的规则。 用汇编语言编写的程序叫汇编语言源程序。 指令除了操作码以外,还有一个操作数问题。 操作数可能放在存储器中,这就涉及操作数的地址。程序中遇到转移指令或调用指令,也需要知道转移地址,若采用具体地址就很不方便,一旦有错,改动也很麻烦。于是人们采用标号或符号来代替地址,例: LP1: mov ax,VAR … loop LP1 汇编语言——指令助记符,符号地址,标号,伪指令等语言元素的集合以及这些元素使用的规则。 用汇编语言编写的程序叫汇编语言源程序。

高级语言 面向过程的语言,如C、C++、BASIC、PASCAL等 优点:更接近人类语言的语法习惯,易于掌握,便于建立数学模型和实现复杂算法 缺点:与机器语言无明显对应关系,因此编译出来的机器语言程序效率相对较低,占用内存多,执行时间长。

汇编程序 汇编源程序需翻译成机器语言,变成可执行文件,机器才能执行,这个翻译过程叫汇编。——高级语言中称该过程为“解释”或“编译”。执行翻译的程序称为“汇编程序”。 汇编语言源程序 汇编程序 机器语言目标程序 源程序的编译程序

汇编语言程序设计与执行过程 输入汇编语言源程序 源文件 .ASM 汇编(编译) 目标文件 .OBJ 链接 可执行文件 .EXE 调试 最终程序 编辑器: EDIT.exe 编程序: MASM.exe 连接程序:LINK.exe 调试程序:DEBUG.exe

一个简单的8086系统下的汇编语言程序: 数据段 代码段 DATA SEGMENT STRING DB ‘HELLO WORLD!’, 0DH, 0AH, ‘$’ DATA ENDS CODE SEGMENT ASSUME CS:CODE, DS:DATA BEGIN: MOV AX, DATA MOV DS, AX ;初始化数据段的段地址 MOV AH, 09H LEA DX, STRING;输出字符串 INT 21H MOV AH, 4CH INT 21H;调用4CH号系统功能返回DOS CODE ENDS END BEGIN 数据段 代码段

第二节 汇编语言语句的组成 一、字符集 汇编语言程序的语句中包含的元素 四、表达式及运算符 二、保留字与标识符 三、常量、变量与标号

一、字符集 允许使用的字符: 注意: 字母,包括大写字母A~Z和小写字母a~z; 数字,包括0~9; 特殊字符,包括:+ - * / =()[ ] < > ; , ‘ “ . — :? @ $ & 及空格、制表符、回车、换行等。 注意: 除了字符串,字母都是不区分大小写 一系列相连的空格、制表符效果相当于一个空格 一系列相连的回车换行相当于一次回车换行 分号“;”后一直到行尾的内容都是注释 字符“&”若用于某行的开头,则表示该行是上一行的续行

二、保留字与标识符 1、保留字 在汇编语言中有特定意义的词,可分为: 指令助记符及指令前缀 如:MOV、ADD、REP等 寄存器名 如:AX、EBX、CL等 伪指令助记符 如: DB、SEGMENT等 其他保留字,包括运算符、操作符等 如: EQ、LT、OFFSET、SEG等

2、标识符 标识符是程序员自己起的名字,如变量名、标号、段名、过程名等 标识符的命名规则: 标识符必须由字母、数字和几个特殊字符(包括 _ @ $ ? :)组成,而且第一个字符不能是数字(否则可能与16进制的数字混淆) 标识符不能与某个保留字相同,以免混淆 尽量用有意义的英文单词或缩写来命名,以增加程序的可读性

三、常量、变量与标号 1、常量 数字常量 二进制:以B结尾,如10101010B 八进制:以Q结尾,如123Q,67Q 十进制:以D结尾,“D”可省略,如1234D,5678 十六进制:以H结尾,A~F开头的数须在前面加“0” 如:1234H,0FFFFH 字符串常量 用单引号或双引号引起来的一个或多个ASCII字符 每个字符的值等于其ASCII码值 例:‘A’=41H一个字节,‘12’=31H、32H两个字节

2、变量 变量是存放在存储器中的操作数 可通过变量的名字来访问变量 变量具有三个属性: 段属性,即变量所在的段的基地址; 偏移量属性,即变量相对于段的起始地址的偏移量; 类型属性,包括BYTE(字节)、WORD(字)、DWORD(双字)

3、标号 标号是一条指令性语句的起始地址 标号具有三个属性: 段属性,即标号所在的段的基地址; 偏移量属性,即标号相对于段的起始地址的偏移量; 类型属性,包括NEAR(近程,即段内)、FAR(远程,即段间)

四、表达式及运算符 由常量、变量、标号和一些运算符、操作符构成的式子 表达式的值在汇编的过程中就已经被汇编程序计算出来 运算符的分类: 算术运算符 逻辑运算符 关系运算符 属性运算符 数值返回操作符

1、算术运算符 五种算术运算: 合法地址表达式:地址-地址(处在同个段中);地址±常数 加:+、 减:-、 乘:*、 除:/、 模:MOD 合法地址表达式:地址-地址(处在同个段中);地址±常数 ADDR1-ADDR2(假设两个地址处在同个段中) ADDR1+1 ADDR2-2 非法地址表达式:地址+地址;地址*地址;地址/地址;常量-地址;地址-地址(处在不同段中) ADDR1+ADDR2 ADDR1*ADDR2 ADDR1/2 100-ADDR1 SEG1_A-SEG2_B (假设两个地址处在不同段中)

2、逻辑运算符 五种逻辑运算: 只用于数字表达式中 例: 与AND、或OR、异或XOR、非NOT、逻辑左移SHL、逻辑右移SHR MOV AL,10101010B AND 11001100B ;AL←10001000B MOV AX,1000100010001000B XOR 1100110011001100B ;AX←0100010001000100B

3、关系运算符 六种关系运算符: 运算结果: EQ(Equal,相等) NE(Not Equal,不等) LT(Less Than,小于) LE(Less than or Equal,小于或等于) GT(Great Than,大于) GE(Great than or Equal,大于或等于) 运算结果: 关系为真,则运算结果为0FFFFH 关系为假,则运算结果为0 如:MOV BX,1 EQ 2; 结果 BX=0 MOV AX,(3 LT 4) AND 1;结果 AX=1

(1)型重新指定操作符PTR 4、属性运算符 功能: 格式: 例: 类型 PTR 表达式 VAR_W DW 1234H 临时指定或修改存储器操作数的数据类型属性或地址类型属性 格式: 类型 PTR 表达式 例: VAR_W DW 1234H MOV AX,VAR_W ;AX←1234H MOV AL,BYTE PTR VAR_W ;AL←34H

PTR与EQU连用 作用: 定义与表达式类型不同的新变量名或新标号,但不分配新的存储单元 例: 数据段定义: 代码段: DATA_B DB 1,2,3,4 DATA_W EQU WORD PTR DATA_B 代码段: MOV AL,DATA_B ;AL←1 MOV AX,WORD PTR DATA_B ;AX←0201H MOV AX,DATA_W ;AX←0201H (第2、3条指令等价)

(2)类型指定操作符THIS 功能: 例1: 例2: 指定或说明变量或标号的类型 DATA_W EQU THIS WORD DATA_B DB 1,2,3,4 MOV AL,DATA_B ;AL←1 MOV AX,WORD PTR DATA_B ;AX←0201H MOV AX,DATA_W ;AX←0201H 例2: ADDR_F EQU THIS FAR ADDR_N: MOV AX,1 JMP ADDR_F ;等价于:JMP FAR PTR ADDR_N

(3)短转移操作符SHORT 一般用在JMP指令 告诉汇编程序该JMP指令是一个短程转移指令 功能: 例: JMP SHORT LAB ……

(1)SEG、OFFSET 5、数值返回操作符 功能: 例如,对于代码段中的一条指令: SEG操作符用于求一个标号或变量所在段的基地址 2000H:1234H ADDR: INC CX ;段地址=2000H,偏移量=1234H 则有: MOV AX,SEG ADDR ;AX←2000H MOV AX,OFFSET ADDR ;AX←1234H ;与指令 “LEA AX,ADDR” 等价

(2)TYPE、LENGTH、SIZE 功能: TYPE:求变量的数值类型属性,即变量具有的字节数 BYTE:返回1;WORD:返回2;DWORD :返回4; NEAR:返回0FFH(-1);FAR:返回0FEH(-2) LENGTH:求变量所占用的内存单元数 用于由重复操作符DUP()定义的存储器变量 对于其他变量,LENGTH的返回值都是1 SIZE:计算变量所占存储器的总字节数 关系: SIZE = LENGTH × TYPE

例: DATA1 DW 1234H DATA2 DB ‘HELLO’ DATA3 DD 100 DUP(0);表示定义100个值为0的双字 MOV AL,TYPE DATA1 ;AL←2 MOV AL,TYPE DATA2 ;AL←1 MOV AL,TYPE DATA3 ;AL←4 MOV BL,LENGTH DATA1 ;BL←1 MOV BL,LENGTH DATA2 ;BL←1 MOV BL,LENGTH DATA3 ;BL←100 MOV CL,SIZE DATA1 ;CL←2×1=2 MOV CL,SIZE DATA2 ;CL←1×1=1 MOV CL,SIZE DATA3 ;CL←4×100=400

6、运算符的优先级 表达式计算顺序: 优先级顺序: 先处理优先级别高的运算符 对于优先级相等的运算符,则按从左至右的顺序进行处理 ()、[](优先级最高) LENGTH、SIZE PTR、THIS、SEG、OFFSET、TYPE HIGH、LOW *、/、MOD、SHL、SHR +、- EQ、NE、LT、LE、GT、GE NOT AND OR、XOR SHORT(优先级最低)

第三节 汇编语言的语句 汇编语言由指令性语句和指示性语句组成 第三节 汇编语言的语句 汇编语言由指令性语句和指示性语句组成 指令性语句由CPU执行,每一条指令性语句都有一条机器码指令与其对应; 指示性语句由汇编程序执行。它指出汇编程序应如何对源程序进行汇编,如何定义变量、分配存储单元以及指示程序开始和结束等。指示性语句无机器码指令与其相对应。 指令性语句汇编时生成机器码; 指示性语句汇编时不生成机器码。

第三节 汇编语言的语句 一、指示性语句 格式([]里的内容可选): 名字:变量名、段名等,与指令地址无关,后面不能加冒号 第三节 汇编语言的语句 一、指示性语句 格式([]里的内容可选): [名字] 伪指令符 操作数,操作数,…… [;注释] 名字:变量名、段名等,与指令地址无关,后面不能加冒号 伪指令符:指定汇编程序要完成的具体操作 操作数:常量、变量或表达式等 注释:说明、解释当前语句的作用 31

1、数据定义伪指令 功能: 格式: 六种数据定义伪指令: 为变量分配存储空间 DB(字节定义):每个操作数占1个字节 [变量名] 伪指令符 操作数,操作数,…… [;注释] 六种数据定义伪指令: DB(字节定义):每个操作数占1个字节 DW(字定义):每个操作数占1个字,即2个字节 DD(双字定义):每个操作数的长度为双字,即4个字节

例: 可同时定义多个数据: NUM DW 12H,-1 ;定义2个字 STRING DB ‘HELLO’,0DH,0AH;定义字符串 省略变量名: BUF DB 1,10,100 DB 1 ;省略变量名 ;但该数据仍可通过“BUF+3”访问 无初始化数据定义:用问号“?”代替操作数 BUFFER DB 2,?,?,? ;定义4个字节 ;其中后3个字节不初始化

DUP操作符: 格式: 重复的次数 DUP(重复的内容) 例: ARRAY DB 3 DUP(1,2) BUF_W DW 100 DUP(?) ;定义100个字,但不初始化 DUP的嵌套使用: ARRAY2 DB 2 DUP(1,3 DUP(0)) ;等价于:ARRAY2 DB 1,0,0,0,1,0,0,0

只能用DW、DD定义 DW:变量/标号的偏移量 DD:变量/标号的段地址和偏移量 例: 地址表达式作为操作数: DATA1 DW ADDR1+1 ;把ADDR1偏移量加1后存放到DATA1对应的存储单元中 DATA2 DD DATA1 ;把DATA1的偏移量和段地址存放到DATA2对应的存储单 元中,其中偏移量放低地址,段地址放高地址。

地址计数器“$” “$”:表示到目前为止该段已经使用的地址空间 例1: 设VAR1地址偏移量为1000H,则: VAR1 DB 100H DUP (?) 之后,$=1100H,因此: ADDR1 DW $ 等价于“ADDR1 DW 1100H”,也等价于“ADDR1 DW ADDR1” 例2: STRING DB ‘ABC’ LEN DW $-STRING ;LEN的值为STRING的长度

2、符号定义伪指令 (1)等价伪指令EQU 格式: 功能: 例: 符号名 EQU 表达式 为常量、表达式及其他各种符号定义一个别名 NUM EQU 12 ;给数值定义符号名 NUM2 EQU NUM+10 ;给12+10=22定义符号名 ADDR EQU DS:[BX+SI] ;给寻址表达式定义符号名 COUNT EQU CX ;给寄存器CX定义符号名 CLEAR EQU XOR AX,AX ;给指令定义符号名

(2)解除伪指令PURGE 格式: 作用: 例: PURGE 符号名,符号名,…… EQU伪指令不能直接对一个符号名重定义,必须先用PURGE解除 例: COUNT EQU CX PURGE COUNT COUNT EQU CL

(3)等号“=”伪指令 格式: 功能: 例: 符号名 = 表达式 为常量、表达式及其他各种符号定义一个等价的符号名 符号名 = 表达式 功能: 为常量、表达式及其他各种符号定义一个等价的符号名 允许对符号名多次重复定义,且以最后一次定义的值为准 例: CONST = 1 ;给数值1定义符号名CONST ADDR = [BP+DI] ;给寻址表达式定义符号名ADDR CONST = 0 ;重定义CONST

3、段定义伪指令 格式: 段名 SEGMENT [定位方式][组合方式][使用类型][‘类名’] 功能:定义一个段 例: …… ;段中的内容 段名 ENDS 功能:定义一个段 例: DATA SEGMENT VAR DB ? DATA ENDS 得到段地址的两种方法: MOV AX,DATA MOV AX,SEG VAR

(1)定位方式 作用: 分类: 设置该段在存储器中的起始边界 BYTE:可从任意的绝对地址开始,如12345H。 WORD:可从偶地址开始。如12346H。 DWORD:可以任何一个双字的边界开始,如12348H。 PARA(缺省方式):必须从存储器的16字节的边界开始,如12340H(最后一位为0)。 PAGE:起始地址必须能被256整除,如12300H。

(2)类名 如:在模块1中有段定义: seg1 SEGMENT PARA STACK ‘stack’ … seg1 ENDS 用单引号括起来的字符串 连接定位时,具有相同类名的逻辑段会被组合在一起 如:在模块1中有段定义: seg1 SEGMENT PARA STACK ‘stack’ … seg1 ENDS 在模块2中有段定义: seg2 SEGMENT PARA STACK ‘stack’ seg2 ENDS 则连接时这两个段被安排在一起。

(3)使用类型(386以上) USE16:缺省类型,表示该段采用16位寻址方式,段基址和段内偏移量都是16位 USE32:表示该段采用32位寻址方式,段选择子为16位,段内偏移量则是32位

(4)组合方式 作用: 分类: 指定同类名段的组合方法 PRIVATE(缺省方式):不组合 PUBLIC:同类名段按照前后次序连接在一起 COMMON:与其他模块中的同类名段有相同的起始物理地址 STACK:与其他模块中的同类名段用覆盖的方式连接,从高地址开始覆盖 MEMORY:该段必须放在同类名的各个段中的最后 AT表达式:直接指定该段的段地址

4、假定伪指令ASSUME 格式: 功能: 例: ASSUME 段寄存器:段名[,段寄存器:段名,……] 告诉汇编程序段与段寄存器的对应关系 DATA SEGMENT VAR1 DB ? DATA ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA BEGIN: …… ASSUME指令:假定CS为代码段,DS为数据段

5、地址对准伪指令 ORG 格式: 功能: 例: ORG 数值表达式 用于指定下一个指令或数据在段内的起始地址 LAB1: PUSH AX ORG 2000H LAB2: MOV AL,34 则LAB2的地址偏移量为2000H。

6、过程定义伪指令PROC、ENDP 功能: 格式: 过程属性: 定义一个过程 NEAR:缺省属性,表示段内调用/返回 …… 返回指令RET 过程名 ENDP 过程属性: NEAR:缺省属性,表示段内调用/返回 FAR:表示段间调用/返回

7、源程序结束伪指令END 格式: 功能: 例: END 标号 标号的地址必须是程序的入口地址,即第一条可执行语句 告诉汇编程序,源程序到此已经结束 告诉汇编程序,源程序的入口地址是多少 例: CODE SEGMENT ASSUME CS:CODE BEGIN: MOV AX,0 ;第一条指令语句 …… CODE ENDS END BEGIN ;源程序到此为止

8、高级数据结构定义伪指令 (1)结构类型数据定义伪指令STRUC/ENDS 结构的定义: 结构名 STRUC …… ;DB、DW之类的数据定义伪指令语句序列 结构名 ENDS 例: DATA STRUC X DW 0 Y DB 1 Z DD 2 DATA ENDS 结构定义时并没有分配存储空间

结构变量的申请与赋初值 结构的访问 结构变量名 结构名 <初始值表> 例: NEW _DATA DATA <,,0> 结构变量名 结构名 <初始值表> 例: NEW _DATA DATA <,,0> ;申请结构变量“NEW _DATA”,其中X=0,Y=1,Z=0 ;缺省的初始值表示使用定义时的预设值 结构的访问 结构变量名.字段名 MOV AX,NEW_DATA.X MOV BL, NEW_DATA.Y

(2)记录定义伪指令RECORD 记录的定义 记录名 RECORD 字段说明,字段说明…… 其中,字段说明的格式是: 字段名:宽度 [=预赋值] 例: REC RECORD A:8=12H, B:5=10, C:3 定义了一个字,其中: A占高8位,预赋值=00010010B B占接下来5位,预赋值=10 C占低3位,预赋值为空

00010010B 00001B 010B 记录变量的的申请与赋初值 格式: 记录变量名 记录名 <初始值表> 例: 记录变量名 记录名 <初始值表> 例: REC_VAR REC <,1,2> 申请了一个变量REC_VAR,其值为: 00010010B 00001B 010B 预赋值12H 初始化为1 初始化为2

记录的访问 WIDTH操作符: 求记录或记录中某个字段的宽度(即位数)。格式: WIDTH 记录名或记录字段名 记录字段名: 求该字段的最低位右移到所在记录最右边所需的移位次数 MASK操作符: 返回一个8位或16位二进制数,这个数中,对应于指定字段的各位均是1,其余各位均是0。格式: MASK 记录字段名 例: MOV AX,REC_VAR ;AX←0001001000001010B MOV BL,WIDTH REC_VAR ;BL←REC_VAR的总宽度16 MOV BH,WIDTH A ;BH←字段A的宽度8 MOV CL,B ;CL←3 MOV DX,MASK C ;DX←0000000000000111B

二、指令性语句 NIL指令 格式: NIL指令并不属于80x86的指令系统 只用于宏汇编中 作用:保留一个空行 例: [标号:] 指令助记符 操作数,操作数,…… [;注释] NIL指令 NIL指令并不属于80x86的指令系统 只用于宏汇编中 作用:保留一个空行 例: L: NIL ;留下一个空行,方便以后对程序的修改 LOOP L 等价于:L:LOOP L

DOS系统功能调用介绍 系统功能调用——由OS提供的一组实现特殊功能的子程序供程序员在程序中调用,以减轻编程工作量。 系统功能调用有两种,一种称为DOS功能调用,另一种称为BIOS功能调用。 用户程序在调用这些系统服务程序时,不是用CALL命令,而是采用软中断指令INT n来实现。 在DOS系统中,功能调用都是用软中断指令INT 21H来实现的。

格式: 将调用功能所需的入口参数存入指定的寄存器或存储单元中; 在寄存器AH中存放所要调用功能的功能号; 执行INT 21H指令,转入中断子程序; 中断子程序运行完后,从指定的寄存器或存储单元中取得出口参数。

(1)单字符显示(功能号:02H) (2)单字符输入(功能号:01H、07H) 功能:将指定的字符送到显示器显示 例: MOV DL,‘A’ ;入口参数,DL存放字符的ASCII码 MOV AH,02H ;02H号功能调用 INT 21H ;显示字符‘A’ (2)单字符输入(功能号:01H、07H) 功能:从键盘输入字符→AL MOV AH,01H;01H号键盘输入功能调用 INT 21H ;AL←输入字符的ASCII码,并显示字符 07H号功能调用与01H号相似,但输入的字符没有在屏幕上显示

(3)检测键盘状态(功能号:0BH) 功能: RUN:…… ;循环运行的程序段 …… MOV AH,0BH ;0BH号功能调用 检测当前时刻键盘是否有键按下。如果有,则出口参数AL=0FFH,否则AL=0。该功能不清除输入缓冲。 例:循环运行程序段,直到有按键按下为止 RUN:…… ;循环运行的程序段 …… MOV AH,0BH ;0BH号功能调用 INT 21H ;检测键盘状态 CMP AL,0 JZ RUN ;AL=0表示没有键按下 MOV AH,01H ;没有清除缓冲,仍可读到按键 INT 21H

(4)直接控制台I/O(功能号:06H) 功能: 输入 / 输出字符: 入口参数DL=0FFH:检测当前时刻键盘是否有键按下。如果有,则出口参数AL=输入的字符,ZF=0,清除输入缓冲区;如果没有,则ZF=1。 入口参数DL≠0FFH:将DL中的ASCII码送显示器上显示 例:循环运行程序段,直到有按键按下为止 RUN:…… ;循环运行的程序段 …… MOV AH,06H ;06H号功能调用 MOV DL,0FFH ;DL=0FFH,输入功能调用 INT 21H ;检测键盘状态 JZ RUN

(5)字符串显示(功能号:09H) 功能: 字符串的首地址→DS:DX中, 字符串一定要以字符‘$’作为结尾标志 例: 将数据段中的字符串输出到屏幕上 字符串的首地址→DS:DX中, 字符串一定要以字符‘$’作为结尾标志 例: DATA SEGMENT STRING DB ‘HELLO’,0DH,0AH,‘$’;需以‘$’结尾 DATA ENDS 代码段: MOV AX,DATA MOV DS,AX ;DS←字符串所在段的段地址 LEA DX,STRING ;DX←字符串首地址的偏移量 MOV AH,09H ;09H号功能调用 INT 21H ;在屏幕上显示“HELLO”

(6)字符串输入(功能号:0AH) 功能:字符串输入,回车键结束 入口参数: DS:DX:缓冲区首地址 (DS:DX):允许输入的最多字符数 例: BUF DB 10H,100 DUP(?);输入字符数不超过16 MOV AX,DATA MOV DS,AX ;DS←缓冲区所在段的段地址 LEA DX,BUF ;DX←缓冲区首地址的偏移量 MOV AH,0AH ;0AH号功能调用 INT 21H ;输入字符串 若输入“123”,则BUF中的内容为: 10H,03H(输入3个字符),31H,32H,33H,0DH(回车)

(7)打印输出(功能号:05H) (8)结束调用(功能号:4CH) 功能:将DL寄存器中的字符送打印机打印 例: MOV DL,‘A’ ;需打印的字符‘A’ MOV AH,05H ;05H号功能调用 INT 21H ;送打印机打印 (8)结束调用(功能号:4CH) 功能:终止当前程序,并返回到DOS中 MOV AH,4CH INT 21H

第四节 宏汇编指令 一、宏操作伪指令 宏定义伪指令 MACRO、ENDM 取消宏定义伪指令 PURGE 第四节 宏汇编指令 一、宏操作伪指令 宏定义伪指令 MACRO、ENDM 取消宏定义伪指令 PURGE 重复伪指令 REPT、IRP、IRPC 局部符号伪指令 LOCAL

1、宏定义伪指令MACRO、ENDM 格式: 例1: 宏名 MACRO [形式参数1,形式参数2,……] …… ;宏体 …… ;宏体 ENDM ;宏定义结束 例1: OUTPUT MACRO MOV AH,02H INT 21H ENDM 则: OUTPUT 等价于 “MOV AH,02H,INT 21H”

例2: OUTPUT MACRO ASC ;“ASC”为形式参数 MOV DL,ASC MOV AH,02H INT 21H ENDM 则: OUTPUT 30H 等价于: MOV DL,30H

2、取消宏定义伪指令PURGE 功能: 使用MACRO定义的宏,如果不再需要,就可以用PURGE来注销 格式: 例: PURGE OUTPUT

3、重复伪指令REPT、IRP、IRPC 格式: 功能: 例如,下面的宏能将AL中的值逻辑左移4位: REPT REPT 表达式 …… ;宏体 ENDM 功能: 重复执行宏体中的语句,重复次数为表达式的值。 例如,下面的宏能将AL中的值逻辑左移4位: REPT 4 SHL AL,1

例,把AX、BX、CX、DX都压入栈中: IRP 格式: IRP 形式参量,<参数,参数,……> …… ;宏体 ENDM 功能: 重复执行宏体,重复的次数是由参数的个数决定 例,把AX、BX、CX、DX都压入栈中: IRP REG,<AX,BX,CX,DX> PUSH REG

格式: 功能: 例如: IRPC IRPC 形式参量,字符串 …… ;宏体 ENDM …… ;宏体 ENDM 功能: 重复执行宏体,其参数列表是字符串,一个字符为一个参数 例如: IRPC NUM,1234 ;“1234”表示4个参数1、2、3、4 DB NUM 等效于:DB 1,2,3,4

4、局部符号伪指令LOCAL 格式: 功能: 例: 正确: 错误: IRP REG,<AX,BX> 将宏中的标号定义为局部符号,避免重复 例: 正确: IRP REG,<AX,BX> LOCAL LAB LAB: PUSH REG ENDM 展开后: ??0000: PUSH AX ??0001: PUSH BX 错误: IRP REG,<AX,BX> LAB: PUSH REG ENDM 展开后: LAB: PUSH AX LAB: PUSH BX (LAB重复使用,出错)

二、条件汇编 格式: 功能: IFxx <条件表达式> …… ;条件块1 [ELSE] …… ;条件块2 ENDIF …… ;条件块1 [ELSE] …… ;条件块2 ENDIF 功能: 根据某个表达式的真假,决定是否对指定的程序段进行编译

第五节 编写完整的汇编语言程序 一、汇编语言程序与MS-DOS 二、一般的汇编语言程序的整体框架 三、模块化程序设计的思想

一、汇编语言程序与MS-DOS 1、DOS的装入功能 确定用于存放程序的内存地址空间 建立程序段前缀PSP(Program Segment Prefix) 100H个字节,存放程序有关信息及进程间的控制信息 最开始的两个字节是一条INT 20H软中断指令 在PSP后装入可执行程序: 数据段 附加段 代码段 堆栈段

初始化各个相关寄存器的值: DS、ES:PSP所在段的段地址 CS、IP:程序的入口地址 SS初始化为堆栈段的段地址 SP指向堆栈段的栈底 入口地址 = 第一条可执行语句的段地址和偏移量 这个地址是从END语句中标号的地址属性得到的 SS初始化为堆栈段的段地址 SP指向堆栈段的栈底

2、DOS的返回 方法一: 执行PSP中的“INT 20H”指令: CS←PSP的段地址 IP←0 具体过程: 程序开头: PUSH DS ;开始时(DS)=PSP的段地址 MOV AX,0 PUSH AX ;“0”入栈 程序过程,要求PUSH与POP配对 程序结束: RET ;CS←PSP的段地址,IP←0

例: CODE SEGMENT ASSUME CS:CODE MAIN PROC FAR BEGIN: PUSH DS ;PSP的段地址入栈 MOV AX,0 ;INT 20H的偏移量为0 PUSH AX ;把偏移量入栈 …… RET ;IP←0,CS←PSP段地址 MAIN ENDP CODE ENDS END BEGIN

方法二: 调用DOS系统的4CH 功能,实现DOS返回: MOV AH,4CH INT 21H 例: CODE SEGMENT ASSUME CS:CODE BEGIN: …… …… MOV AH,4CH ;返回DOS INT 21H CODE ENDS END BEGIN

二、一般的汇编语言程序的整体框架 数据段、附加段 注释 堆栈段 END伪指令 ASSUME伪指令 代码段

源程序结构框架 框架一: 数据段 堆栈段 DATA SEGMENT ;数据段 …… ;定义变量、缓冲区等 DATA ENDS …… ;定义变量、缓冲区等 DATA ENDS STACK SEGMENT PARA STACK ‘STACK’ ;堆栈段部分 DB XXXX DUP(?) ;定义堆栈的长度 STACK ENDS CODE SEGMENT ;代码段部分 ASSUME CS:CODE,DS:DATA,SS:STACK,ES:DATA MAIN PROC FAR BEGIN: PUSH DS MOV AX,0 ; 为RET提供转移地址 PUSH AX 数据段 堆栈段

MOV AX,DATA MOV DS,AX ;初始化段寄存器DS、ES MOV ES,AX …… ;程序部分 RET ;返回DOS MAIN ENDP PROC_1 PROC NEAR/FAR …… ;定义其他过程 RET PROC_1 ENDP CODE ENDS END MAIN

框架二: 采用“4CH”功能返回:(代码段部分) CODE SEGMENT ;代码段 ASSUME CS:CODE,DS:DATA, & SS:STACK,ES:DATA BEGIN: MOV AX,DATA MOV DS,AX ;初始化DS、ES MOV ES,AX …… ;程序部分 MOV AH,4CH ;4CH号功能调用 INT 21H ;返回DOS CODE ENDS END BEGIN

三、模块化程序设计的思想 1、模块命名伪指令NAME、TITLE 2、逻辑段与物理段 格式: 作用: 为模块命名,指示给连接程序进行连接用 编译连接时,同类逻辑段将组合成一个大的物理段

3、同类名的组合方式 PRIVATE(缺省方式):不组合 PUBLIC:同类名段按照前后次序连接在一起 COMMON:与其他模块中的同类名段有相同的起始物理地址 STACK:与其他模块中的同类名段用覆盖的方式连接,从高地址开始覆盖 MEMORY:该段必须放在同类名的各个段中的最后 AT表达式:直接指定该段的段地址

4、模块之间的通信 格式: 功能: PUBLIC与EXTRN: PUBLIC 标识符,标识符,……

例: 模块1: NAME MOD1 PUBLIC VAR1 ;公用标识符VAR1 DATA1 SEGMENT PARA PUBLIC ‘DATA’ VAR1 DB ? ;字节变量VAR1 DATA1 ENDS 模块2: NAME MOD2 EXTRN VAR1:BYTE ;说明VAR1是字节 CODE2 SEGMENT PARA PUBLIC ‘CODE’ …… MOV AL,VAR1 ;访问MOD1中的字节变量VAR1

第六节 汇编语言程序设计 一、程序设计基本方法 分析实际问题,确定基本思路及程序算法 绘制程序流程图 根据流程图编写程序 调试程序

1、流程图 起止框:表示程序的开始和结束 工作框:说明该步骤的功能 判断框:说明判断的条件 调用框:说明调用过程的名字、参数等 连线: 表示程序的走向 功能 条件? 子程序 起止框 工作框 条件框 调用框 连线

2、程序的基本结构形式 顺序结构 分支结构 按直线顺序执行程序 含判断语句,根据判断结果选择分支 例: CMP AL,BL JZ L1 ;相等 L2: …… ;不等 JMP NEXT L1: …… NEXT:…… 程序段1 程序段2 程序段3 顺序结构 条件? 程序段1 程序段2 分支结构 Y N

(3)循环结构 初始化部分 循环体部分 循环条件判断部分 例: MOV CX,100 ;初始化部分 L: …… ;循环体开始 …… DEC CX ;修改循环变量 JNZ L ;循环条件判断 条件? 循环体 初始化 循环结构 Y N

(4)子程序结构 寄存器的保护与恢复 主程序与子程序之间的参数传递 子程序可嵌套调用 在程序中需要多次出现的程序段,可定义为一个子程序,在主程序需要的时候就可以直接调用它 寄存器的保护与恢复 主程序与子程序之间的参数传递 子程序可嵌套调用 程序段1 程序段2 过程调用 子程结构

子程序嵌套

二、程序设计举例 (1)顺序结构--32位无符号数相乘 H1 L1 H2 L2 L2×L1 L2×H1 H2×L1 H2×H1 64位结果 思路:分为高字部分和低字部分,模拟笔算的方法,做4次16位的乘法运 算,得到4个部分和A、B、C、D,再加起来得到结果 H1 L1 H2 L2 L2×L1 L2×H1 H2×L1 H2×H1 64位结果 被乘数 乘数 部分和A 部分和B 部分和C 部分和D × + 92

32位无符号数相乘流程图 开始 计算部分和C= 计算部分和A= C的低字部分叠加至RES+2 C的高字部分叠加至RES+4 计算部分和B= A的低字部分 RES A的高字部分 RES+2 B的低字部分叠加至RES+2 B的高字部分叠加至RES+4 计算部分和C= 计算部分和D= C的低字部分叠加至RES+2 C的高字部分叠加至RES+4 D的低字部分叠加至RES+4 D的高字部分叠加至RES+6 结束 开始 32位无符号数相乘流程图

DATA SEGMENT MUL1 DW 5678H, 1234H ;被乘数12345678H MUL2 DW 789AH, 3456H ;乘数3456789AH RES DW 4 DUP(0) ;存放64位结果,初始化为0 DATA ENDS CODE SEGMENT ASSUME CS:CODE, DS:DATA MAIN PROC FAR PUSH DS MOV AX, 0 PUSH AX MOV AX, DATA MOV DS, AX 94

;计算部分和A=L2×L1 MOV AX, MUL2 ;AX←L2 MUL MUL1 ;(DXAX)←L2×L1 MOV RES, AX ;保存A的低字部分 MOV RES+2, DX ;保存A的高字部分 ;计算部分和B=L2×H1 MUL MUL1+2 ;(DXAX)←L2×H1 ADD RES+2, AX ;叠加B的低字部分 ADC RES+4, DX ;叠加B的高字部分 ;计算部分和C=H2×L1 MOV AX, MUL2+2 ;AX←H2 MUL MUL1 ;(DXAX)←H2×L1 ADD RES+2, AX ;叠加C的低字部分 ADC RES+4, DX ;叠加C的高字部分 95

相乘结果: 03B8C7B8E8544430H ;计算部分和D=H2×H1 MOV AX, MUL2+2 ;AX←H2 MUL MUL1+2 ;(DXAX)←H2×H1 ADD RES+4, AX ;叠加D的低字部分 ADC RES+6, DX ;叠加D的高字部分 RET MAIN ENDP CODE ENDS END MAIN 相乘结果: 03B8C7B8E8544430H 96

(2)分支结构—符号函数的实现

开始 初始化指针、循环次数 读入 x的值 x AL=0FFH AL=00H AL=01H 保存AL,修改指针 完成? 结束 <0 >0 =0 N Y

DATA SEGMENT X DB 12H,34H,00H,0FFH,0ABH ;X的值 COUNT EQU $-X ;X的个数 SGNX DB COUNT DUP(?) ;保存结果 DATA ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA,ES:DATA MAIN PROC FAR PUSH DS MOV AX,0 PUSH AX MOV AX,DATA MOV DS,AX MOV ES,AX LEA SI,X ;初始化源指针 LEA DI,SGNX ;初始化目的指针 MOV CX,COUNT ;循环次数

AGAIN:LODSB ;读入X的值 OR AL,AL ;把X的特征反映在标志寄存器上 JZ ZERO ;如果ZF=0,则说明X=0 JS MINUS ;如果SF=1,则说明X<0 MOV AL,01H ;否则X>0,所以sgn(x)=1 JMP NEXT ZERO:MOV AL,00H ;X=0,所以sgn(x)=1 MINUS:MOV AL,0FFH ;X<0,所以sgn(x)=-1 NEXT:STOSB LOOP AGAIN RET MAIN ENDP CODE ENDS END MAIN

(3)循环结构--显示二进制数的ASCII码形式 在内存中有几个8位的二进制数,编写程序将它们转换成二进制数的ASCII码,并输出到屏幕上,例如对于字节12H,转换后能在屏幕上显示“0001 0010B”

开始 初始化指针SI、计数值CX DL=30H BH逻辑左移1位 N CF=0? Y 显示字符 BL减1 BL=0? SI加1,CX减1 转换完成? DL加1 N Y 结束

DATA SEGMENT NUM DB 12H,34H,0ABH,0CDH ;需显示的字节 COUNT EQU $-NUM ;字节数 AFTER DB 'B',0DH,0AH,'$' ;‘B’、回车换行 DATA ENDS CODE SEGMENT ASSUME CS:CODE, DS:DATA MAIN PROC FAR PUSH DS MOV AX, 0 PUSH AX MOV AX, DATA MOV DS, AX 103

LEA SI, NUM ;数据的地址 MOV CX, COUNT ;字节数 AGAIN: MOV BH, [SI] ;需显示的数←BH MOV BL, 8 ;左移8次 PRINT: MOV DL, 30H SHL BH, 1 ;逻辑左移1位 JNC ZERO ;CF=0,则DL=30H INC DL ;CF=1,则DL=31H ZERO: MOV AH, 02H INT 21H ;显示‘0’或‘1’ DEC BL ;是否8个位都显示 JNZ PRINT ;否,则继续 LEA DX, AFTER ;显示‘B’、回车换行 MOV AH, 09H INT 21H

INC SI LOOP AGAIN ;循环显示所有字节 RET MAIN ENDP CODE ENDS END MAIN 运行结果: 00010010B 00110100B 10101011B 11001101B

(4)子程序结构--显示16进制数的ASCII码形式 在内存中有几个16位的二进制数,编写程序将它们转换成16进制数的ASCII码,并输出到屏幕上,如对于数字1234H,须将其转换成“1”、“2”、“3”、“4”四个字符,并分别送显示器显示 编程时,把对每个二进制数的处理写成一个子程序SHOW_W ,在这个子程序中,将二进制数每4位分成一段,每段又调用子程序SHOW_1 ,转换成ASCII码并输出

读取高8位 前4位 SHOW_1 后4位 读取低8位 显示’H’,换行 返回 (b) SHOW_W >9? DL+30H DL+7H 显示字符 (c) SHOW_1 N Y 二进制转16进制ASCII码的程序流程图 初始化SI CX←个数 SHOW_W 完成? 开始 结束 (a) MAIN

DATA SEGMENT NUM DW 1234H, 5678H, 9ABCH, 0DEF0H ;要显示的数字(字) LTH_W DW ($-NUM)/2 ;数字的个数(每个数占2字节) AFTER DB ‘H’, 0DH, 0AH,‘$’ ;每个数后面显示“H”然后回车换行 DATA ENDS STACK SEGMENT PARA STACK 'STACK' DB 100 DUP(?) ;堆栈长度 STACK ENDS CODE SEGMENT ASSUME CS:CODE, DS:DATA, SS:STACK MAIN PROC FAR PUSH DS MOV AX, 0 PUSH AX ;保存DOS返回指令的地址 MOV AX, DATA MOV DS, AX ;初始化DS MOV CX, LTH_W LEA SI, NUM

L: CALL SHOW_W ;调用子程序显示一个数字 INC SI INC SI ;一个数字占用2字节 LOOP L RET MAIN ENDP SHOW_W PROC ;子程序,能将[SI]中的16位数字显示出来 PUSH CX ;保护CX MOV DL, [SI+1] ;先处理高8位 MOV CL, 4 SHR DL, CL ;前4位 CALL SHOW_1 ;显示前4位的16进制数 MOV DL, [SI+1] AND DL, 0FH ;后4位 CALL SHOW_1 ;显示后4位的16进制数

MOV DL, [SI] ;再处理低8位 MOV CL, 4 SHR DL, CL ;前4位 CALL SHOW_1 ;显示前4位的16进制数 MOV DL, [SI] AND DL, 0FH ;后4位 CALL SHOW_1 ;显示后4位的16进制数 LEA DX, AFTER MOV AH, 09H INT 21H ;显示数字后面的“H”,并回车、换行 POP CX ;恢复CX RET SHOW_W ENDP

SHOW_1 PROC CMP DL, 9 JBE NEXT ADD DL, 7 ;如果大于9,则需加37H,如‘A’=41H=10+7+30H NEXT: ADD DL, 30H;如果不大于9,则需加30H,如‘1’=31H=1+30H MOV AH, 02H INT 21H ;显示一位16进制数 RET SHOW_1 ENDP CODE ENDS END MAIN 程序运行结果,屏幕上显示: 1234H 5678H 9ABCH DEF0H

其他例子: 逻辑尺控制程序 例:对BUF中16个字节进行处理: 将第1、3、7、12、16个数据的值减2 将其它数据的值加3 利用逻辑尺: (AX) = 0101110111101110B AX逻辑左移1位 移出的位 = 0:BUF[SI]的值-2; 移出的位 = 1:BUF[SI]的值+3; 循环上一步16次

开始 初始化指针、循环次数 读入逻辑尺的值 读入一个数据 左移逻辑尺 数据的值-2 数据的值+3 结束 N Y CF=0? 保存数据,修改指针、循环次数 循环完成? 结束 N Y

DATA SEGMENT BUF DB 12,23,34,45,56,67,78,89,98,87,76,65,54,43,32,21 RES DB 16 DUP(?) ;存放结果的缓冲区 LOG_RUL DW 5DEEH ;逻辑尺 DATA ENDS CODE SEGMENT ASSUME CS:CODE, DS:DATA, ES:DATA MAIN PROC FAR PUSH DS MOV AX, 0 PUSH AX MOV AX, DATA MOV DS, AX MOV ES, AX

LEA SI, BUF LEA DI, RES MOV BX, LOG_RUL ;读入逻辑尺常数 MOV CX, 16 ;循环次数 AGAIN: LODSB ;读入温度值 SHL BX, 1 ;逻辑尺左移 JC PROC1 ;如果CF=1则转“+3”程序段 PROC0: SUB AL, 2 ;否则CF=0,进行“-2”运算 JMP NEXT PROC1: ADD AL, 3 ;“+3”运算 NEXT: STOSB ;处理完毕保存结果 LOOP AGAIN ;循环处理 RET MAIN ENDP CODE ENDS END MAIN

本章结束!