汇编语言程序设计基础 汇编源程序的基本结构形式 ——介绍汇编语言程序设计的常用结构与方法 模块和段

Slides:



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

微型计算机技术 教 学 指 导(七) 太原广播电视大学 郭建勇.
第10章 DOS功能调用与BIOS中断调用.
第7章 8086/8088汇编语言程序设计 7.1 引言 7.2 顺序程序设计 7.3 分支结构程序设计 7.4 循环结构程序设计
第四章 汇编语言 程序设计 任课教师:王晓甜
大连理工大学软件学院 软件工程系 赖晓晨 计算机组成与结构 大连理工大学软件学院 软件工程系 赖晓晨
本周实验安排 实验内容:(P231)人名排序的例子。
第4章 MCS-51程序设计 4.1 汇编语言的格式与伪指令 4.2 汇编语言程序设计步骤 4.3 查表程序设计 4.4 循环程序设计
微机原理与接口技术 微机原理与接口技术 朱华贵 2015年10月30日.
第3章 80x86汇编语言程序设计(下).
4.1 汇编语言 4.2 顺序结构程序 4.3 分支程序设计 4.4 循环程序设计 4.5 子程序设计
第3章 80x86汇编语言程序设计(上) 16位汇编版本 时间不够的情况下只讲16位汇编.
9.1 可编程并行输入/输出接口芯片8255A 9.2 可编程计数器/定时器 可编程串行输入/输出接口芯片8251A
3.3.5 程序控制指令 控制转移指令分为: 转移指令 循环控制指令 调用和返回指令 中断指令.
微机原理与接口技术 微机原理与接口技术 朱华贵 2015年11月26日.
第5章 循环与分支程序设计  循环程序设计  分支程序设计.
第八章 代码转换 8.1 概述 代码转换是在计算机程序设计中经常碰到的问题。如二进制数与十进制数的转换,ASCII码表示的十进制数与十六进制数之间的转换等等。 代码转换可以用硬件快速实现,但更常用的方法还是用软件的方法来实现。用软件处理代码转换的方法通常有以下两种方法: 1、用查表的办法:这种方法主要用于代码之间的转换关系比较复杂的情况。但码元的数量必须是有限的。
汇编语言程序设计 Assembly Language Programming
第三章 寻址方式与指令系统 3.1 寻址方式 一条指令通常由两大部分构成: 操作码 操作数
第7章 并行接口 7.1 简单并行接口 7.2 可编程并行接口8255A 7.3 键盘接口 7.4 LED显示器接口.
微机原理与接口技术 第2章 8086系统结构 朱华贵 2015年09月17日.
第九章 计数器和定时器电路 第一节 概述 第二节 Intel 8253的控制字 第三节 Intel 8253的工作方式 第九章 计数器和定时器电路 第一节 概述 第二节 Intel 8253的控制字 第三节 Intel 8253的工作方式 第四节 Intel 8253在IBM PC机上的应用.
Assembly Language Programming
微机原理与接口技术 微机原理与接口技术 朱华贵 2015年12月10日.
微机原理与接口技术 微机原理与接口技术 朱华贵 2015年11月05日.
输入输出与中断 主要内容 CPU与外设之间数据传送方式 中断技术 8086中断系统和中断处理.
第八章 输入输出程序设计 总线 CPU MEM I/O接口 I/O设备.
第4章 8086汇编语言程序设计 几个概念 8086汇编语言的语句 8086汇编中的伪指令 8086汇编中的运算符 汇编语言程序设计
第3章 IA-32指令系统 3.1 基本数据类型 3.2 IA-32的指令格式 3.3 IA-32指令的操作数寻址方式
第8章 寻址方式与指令系统.
第4章 汇编语言程序设计 4.1 程序设计语言概述 4.2 汇编语言的程序结构与语句格式 4.3 汇编语言的伪指令
走进编程 程序的顺序结构(二).
微机原理与接口技术 ——80x86微处理器 西安邮电大学 计算机学院 范琳.
第一章 8086程序设计 第二章 MCS-51程序设计 第三章 微机基本系统的设计 第四章 存贮器与接口 第五章 并行接口
微机原理与接口技术 微机原理与接口技术 朱华贵 2015年11月20日.
汇编语言程序设计课程设计 第二次实验 DEBUG基本命令与算术运算指令
微型计算机原理及应用.
第3章 微型计算机输入输出接口 3.1 输入/输出接口 3.2 输入输出数据传输的控制方式 3.3 开关量输入输出接口 欢迎辞.
第六章 子程序结构 §6.1 子程序的设计方法 §6.2 嵌套与递归子程序 §6.3 子程序举例 §6.4 DOS系统功能调用.
第 13 章 中断系统.
條件處理.
第九章 高级宏汇编语言 9.1 结构 结构就是将逻辑上有一定关系的一组数据,以某种方式组合在一起所形成的数据形式。
第5章 循环与分支程序设计 学习目标: 了解并掌握循环程序的构造方法,尤其是对循环控制条件的设置以及可能出现的边界情况的考虑。掌握起泡排序算法这种多重循环程序设计中的常用方法。交换标志位的设置在此算法中更能提高效率。学会在数组排序算法中采用折半查找法来提高查找效率。学会使用跳跃表法实现CASE结构。
4.1 汇编语言程序格式 4.2 MASM中的表达式 4.3 伪指令语句 4.4 DOS系统功能调用和BIOS中断调用
微机原理与接口技术 微机原理与接口技术 朱华贵 2015年11月19日.
第五章:输入输出基本技术 主讲教师:范新民.
第4章 汇编语言程序格式  汇编程序功能  伪操作  汇编语言程序格式  汇编语言程序的上机过程.
第10章 可编程外围接口芯片8255A及其应用 10.1 概述 A的工作原理 A的应用举例.
习题3 1、 分别说明下列指令的原操作数和目的操作数各采用什么寻址方式。 设定如下: ①立即寻址 ② ① ②寄存器寻址
3.4.2 算术运算指令(Arithmetic) 算术运算指令内容: 8086/8088提供加、减、乘、除等六种基本算术操作
第九章 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日.
第八章 中断系统.
本节内容 内存复制指令 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
微机原理与接口技术 西安邮电大学计算机学院 宁晓菊.
College of Computer Science & Technology
微机原理与接口技术 微机原理与接口技术 朱华贵 2015年11月06日.
C++语言程序设计 C++语言程序设计 第一章 C++语言概述 第十一组 C++语言程序设计.
循环程序设计 在程序中包含重复执行的程序段称为循环程序设计。循环程序可以使程序结构性强、可读性好,从而大大提高了程序质量。
第6章 子程序结构 在程序设计中,我们会发现一些多次无规律重复的程序段或语句序列。解决此类问题一个行之有效的方法就是将它们设计成可供反复调用的独立的子程序结构,以便在需要时调用。在汇编语言中,子程序又称过程。 调用子程序的程序称为主调程序或主程序。 2019/7/20 ch6.
微机原理与接口技术 第5章 汇编语言程序设计 西安邮电大学计算机学院 王 钰.
第4章 MCS-51汇编语言程序设计 教学基本要求: (1)、了解MCS-51汇编语言程序设计的特点;
第4章 汇编语言程序格式  汇编程序功能  伪操作  汇编语言程序格式  汇编语言程序的上机过程
第三章 8086的指令系统 8086指令特点 8086的寻址方式 8086的指令格式及数据类型 8086的指令集.
第五章 循环与分支程序设计 ch5 2019/9/19.
跟我一起学编程系列课程: 第一篇汇编语言 16位汇编.
Presentation transcript:

汇编语言程序设计基础 汇编源程序的基本结构形式 ——介绍汇编语言程序设计的常用结构与方法 模块和段 与大多数高级语言相同的是: 汇编语言是结构化的语言。一个大的汇编源程序可由多个“模块”组成,而每个模块则由一个或多个“段”构成。 与高级语言不同,使用汇编语言编程时需同时使用指令和伪指令。 汇编源程序的基本结构形式 模块和段 一个汇编“模块”可以包含一个或几个长度小于64KB的“段” 8086只有4个段寄存器(CS、DS、SS和ES) CS: 程序段 DS: 数据段 SS: 堆栈段 ES: 附加段(可选)

汇编语言程序设计基本上与高级语言程序设计一样,一般步骤: 1 程序设计的基本过程 一、程序设计的一般步骤 汇编语言程序设计基本上与高级语言程序设计一样,一般步骤: 1.分析问题并抽象出数学模型。 2.确定最佳算法。 3.画出程序结构框图和流程图。 4.合理分配内存工作单元和寄存器,并了解I/O接口地址。 5.编程并调试。(有时需要用注释行说明程序,便于阅读和修改。) 模块化设计方法 “自顶向下,逐步细化” 结构化编码方法 顺序、分支、循环三种基本结构 二、评价程序质量的标准 1.合理组织数据,发挥存贮器、Reg的作用。 2.程序逻辑结构好,便于二次开发。 3.可读性强。 4.高可靠性和可维护性。 5.效率高(代码少)。

2 程序的基本结构 三种基本结构奠定了实现任何复杂程序的基础。 一、顺序结构 ——对应简单程序,顺序执行,无转移、无循环。指令指针IP值线性增加。 二、分支结构 ——依据不同条件分支到各程序段,有双分支和多分支两种。IP值受标志位的影响而跳变。 顺序结构 分支结构 两个分支 Y N 分支结构 三个分支 三、循环结构 ——实现那些 需要重复做的工作。IP值因计数器CX中的值不为零而循环。

循环结构 循环初始设置 循环初始设置 N 循环条件判断? 循环体 Y 循环体 N 循环条件判断? Y 直到型循环 当型循环 (当条件成立进入循环) 循环初始设置 循环体 循环条件判断? Y N Y N 循环初始设置 循环体 循环条件判断? 直到型循环 (直到条件成立退出循环)

一、顺序结构程序设计 ——按事件发展的先后,选择合适的指令有序地加以组合。 例1 用8086CPU的指令实现Y=(X1+X2)/2的程序设计 (1)明确任务,确定算法。 (2)绘流程图

取变量X1送AL 取变量X2送AL 计算X1+X2送AX 结果送Y 计算AX/2 结束 开始 图5-3 例5-1流程图

(3)根据流程图编写汇编语言程序 1 DATA SEGMENT 2 X1 DB ? 3 X2 DB ? 4 Y DW ? 5 DATA ENDS 6 CODE SEGMENT 7 ASSUME CS:CODE, DS:DATA, 8 MAIN PROC FAR ;设置远程调用子程序 9 START: PUSH DS ;将DS:0压入堆栈 10 MOV AX, 0

11 PUSH AX 12 MOV AX, DATA ;为DS设置段值 13 MOV DS, AX 14 MOV AL, X1 ;取变量X1送AL 15 MOV BL, X2 ;取变量X2送BL 16 ADD AL, BL 17 ADC AH, 0 ;X1+X2+进位送AX 18 SAR AX, 1 19 MOV [Y], AX ;结果送Y 20 RET 21 MAIN ENDP 22 CODE ENDS 23 END START

例5-2 将一位十六进制数转换成与它相应的 ASCⅡ码。 (1)明确任务,确定算法。 (2)绘流程图(图5-4) 开始 BX←表起始地址 例5-2 将一位十六进制数转换成与它相应的 ASCⅡ码。 (1)明确任务,确定算法。 (2)绘流程图(图5-4) BX←表起始地址 AL←HEX AL←((BX)+(AL)) ASCI←AL 开始 结束

(3)根据流程图编写汇编语言程序 DATA SEGMENT TABLE DB 30H,31H,32H,33H,34H,35H,36H,37H DB 38H,39H,41H,42H,43H,44H,45H,46H HEX DB 8 ASC DB ? DATA ENDS COSEG SEGMENT ASSUME CS:COSEG,DS:DATA BEING: MOV AX,DATA MOV DS,AX

MOV BX, OFFSET TAB MOV AL,HEX XLAT MOV ASC,AL MOV AH,4CH INT 21H COSEG ENDS END BEING

(BX)<= X*X (AX)<= Y/5 Z <=(BX)-(AX) PUSH DS SUB AX, AX PUSH AX MOV AX, DAT MOV DS, AX 例:编程计算表达式Z = X2-Y/5的值,其中X、Y为带符号字节整数,Z为带符号字整数。 MOV AL, X IMUL AL MOV BX, AX (BX)<= X*X (AX)<= Y/5 Z <=(BX)-(AX) 开 始 结束 MOV AL, Y CBW MOV CL, 5 IDIV CL SUB BX, AX MOV Z, BX RET

程 序 DAT SEGMENT X DB 10 DAT ENDS ASSUME DS: DAT, CS: COD 程 序 ;-- 数据段定义 ---------------------------------- DAT SEGMENT X DB 10 Y DB - 20 Z DW ? DAT ENDS ;-- 代码段定义 ---------------------------------- COD SEGMENT ASSUME DS: DAT, CS: COD MAIN PROC FAR PUSH DS ; 固定格式返回DOS系统 SUB AX, AX PUSH AX MOV AX, DAT MOV DS, AX ; 初始化DS

程 序(续) ;---------------------------------------------------------------------------- MOV AL, X IMUL AL MOV BX, AX ; (BX)<= X*X ;----------------------------------------------- MOV AL, Y CBW ; 将被除数扩展为字数据 MOV CL, 5 IDIV CL CBW ; (AX)<= Y/5 ;------------------------------------------------ SUB BX, AX MOV Z, BX ; Z <= (BX)-(AX) ;---------------------------------------------------- RET ; 过程结束,返回DOS MAIN ENDP COD ENDS END MAIN

思考题:压缩BCD码分解为非压缩BCD码。 例2:将某段中的字符串“Hello!”传送到另一段中(内存数据块 的传送)。 开始 建立传送方向 DS: SI ← 源串首地址 ES: DI ←目的串首地址 CX 串长度 串传送 返回 DOS 利用变量定义字符串和缓冲区 思考题:压缩BCD码分解为非压缩BCD码。

aa SEGMENT ;数据段1 xx DB 'Hello!’ ;定义源串 aa ENDS bb SEGMENT ;数据段2 yy DB 6 dup (?) ; 定义目的缓冲区 bb ENDS cc SEGMENT ;代码段 ASSUME CS:cc, DS:aa, ES:bb ;指示指令中标号、变量所在段 start : CLD ;设置传送方向 MOV AX , aa ;DS: SI ← 源串首地址 MOV DS , AX LEA SI , xx MOV AX , SEG yy ;ES:DI ← 目的首地址 MOV ES , AX MOV DI , OFFSET yy MOV CX , 6 ;CX ← 串的长度 REP MOVSB ;串传送 MOV AH , 4CH ;调用4CH系统功能,返回DOS INT 21H cc ENDS END start ;指示程序结束和程序入口

设计分支程序的关键: ① 如何判断分支的条件 ② 如何实现分支结构 1. 利用比较和转移指令实现分支 第4章 汇编语言程序设计 二、分支结构程序的设计 设计分支程序的关键: ① 如何判断分支的条件 ② 如何实现分支结构 1. 利用比较和转移指令实现分支 方法:在需要分支的地方用比较指令CMP、串比较指令CMPS 或串搜索指令SCAS等,进行分支条件的比较判断, 再利用各种条件转移指令实现分支。 例1:编程实现下列函数的功能,其中X、Y为无符号字节数。

流程图 Y N Y N (AL)=(BL)? (AL)>(BL)? 第4章 汇编语言程序设计 PUSH DS SUB AX, AX PUSH AX MOV AX, DAT MOV DS, AX 流程图 (AL)<= X (BL)<= Y 开 始 MOV AL, X MOV BL, Y CMP AL, BL JE C1 JA C2 (AL)=(BL)? Z <= 0 Y C2: MOV AL, 1 JMP EXT (AL)>(BL)? N Z <= 1 Y MOV AL, -1 Z <= -1 N 结束 C1: MOV AL, 0 JMP EXT EXT: MOV Z, AL RET

程 序 ;-- 数据段定义 ---------------------------------- DAT SEGMENT X DB 242 程 序 ;-- 数据段定义 ---------------------------------- DAT SEGMENT X DB 242 Y DB 67 Z DB ? DAT ENDS ;-- 代码段定义 ---------------------------------- COD SEGMENT ASSUME DS: DAT, CS: COD MAIN PROC FAR PUSH DS ; 保存返回地址 SUB AX, AX PUSH AX MOV AX, DAT MOV DS, AX ; 初始化DS

程 序(续) ;--------------------------------------------------------------------------------------- MOV AL, X MOV BL, Y CMP AL, BL JE C1 ; (AL)=(BL) 则跳转至C1,否则继续执行 JA C2 ; (AL)> (BL) 则跳转至C2,否则继续执行 MOV AL, -1 EXT: MOV Z, AL RET ; 返回DOS C1: MOV AL, 0 JMP EXT C2: MOV AL, 1 ;---------------------------------------------------------------------------------------- MAIN ENDP COD ENDS END MAIN

例2. 变量X的符号函数用下式表示。编程实现根据X的值给Y赋值。 例3. 数据块的传送。 考虑: ① 设数据在同一段内传送 将一块存储区既看作数据段,又看作附加段。 ②不重叠 CLD,直接用MOVS或MOV 源首址> 目标首址 ③ 重叠 CLD 增量传送 源首址<目标首址 STD 减量传送

程序如下: DATA SEGMENT STRG DB 1000 DUP(?) ;数据区起始 STG1 EQU STRG+7 ;定义源串存放区 STRSE EQU 50 DATA ENDS STACK SEGMENT PARA STACK ‘STACK’ DB 100 DUP(?) STACK ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA,ES:DATA MAIN: MOV AX,DATA MOV DS,AX ;DS指向数据段 MOV ES,AX ;ES指向数据段 MOV CX, STRSE ;串长→CX

MOV SI,OFFSET STG1 ;源串首地址→SI MOV DI,OFFSET STG2 ;目标串首地址→DI CLD ;增量方式传送 PUSH SI ADD SI,STRSE-1 ;SI=源串末地址 CMP SI,DI ;DI=目标串首地址 POP SI JL OK ;源串地址与目标串地址不重叠,转OK处 STD ;否则,按减量方式传送 ADD SI,STRSE-1 ;指向数据块底部 ADD DI,STRSE-1 OK: REP MOVSB ;重复传送50个数据 MOV AX,4C00H INT 21H CODE ENDS END MAIN

5.3.1 二分支结构 例5-3 要求对不足250个的学生成绩进行统计分析,统计出优秀、及格和不及格的人数。 (1)明确任务,确定算法。

(2)绘流程图 开始 SI←BUF首址 取总学生数CH←[SI] AH<60H? BX←0, SI←SI+1 取学生成绩AH←[SI] 结束 开始 SI←BUF首址 取总学生数CH←[SI] BX←0, SI←SI+1 取学生成绩AH←[SI] AH<90? AH<60H? BH←BH+1 BL←BL+1 SI←SI+1 CH←CH-1 SI←存储区首址 [SI]←BH [SI+1]←BL [SI+2]←CL CH=0? Y N CL←CL+1 图5-6 例5-3流程图

(3)根据流程图编写汇编语言程序 DATA SEGMENT BUF DB N DB N DUP(?) NUM DB 3 DUP(?) DATA ENDS CODE SEGMENT MAIN PROC FAR ASSUME CS:CODE,DS:DATA START: PUSH DS SUB AX,AX PUSH AX MOV AX,DATA MOV DS,AX MOV SI,OFFSET BUF MOV CH,[SI] ;学生个数N→CH MOV CL,0 ;CL存不及格人数

  MOV BX,0 ;BH存优秀人数,BL存及格人数 INC SI LP: MOV AH, [SI] ;取学生成绩 CMP AH,90 JB BLOW90 ;小于90转 INC BH ;优秀人数加1 JMP ABOV60 BLOW90: CMP AH,60 JB BLOW60 ;小于60转 ABOV60: INC BL ;及格人数加1 JMP NEXT BLOW60: INC CL ;不及格人数加1 NEXT: INC SI ;数组地址加1 DEC CH ;计数减1 JNZ LP MOV SI,OFFSET NUM MOV [SI],BH ;优秀人数送入内存单元 MOV [SI+1],BL ;及格人数送入内存单元

MOV [SI+2],CL ;不及格人数送入内存单元 RET MAIN ENDP CODE ENDS END START 5.3.2 多分支结构 1.条件逐次测试法 例5-4 编程实现使键盘上A、B、C、D六个字母键成为4条输     入命令,使之分别对应不同算法的控制子程序。 (1)明确任务,确定算法。 (2)绘流程图略

(3)汇编语言程序 MOV AH,l INT 21H ;1号功能调用,键盘接收 CMP AL,‘A’ ;键值为A,转PA子程序 JE PA CMP AL,‘B’ ;键值为B,转PB子程序 JE PB CMP AL,‘C’ ;键值为C,转PC子程序 JE PC CMP AL,‘D’ ;键值为D,转PD子程序 JE PD HLT ;键值非A、B、C、D,停止 PA: … ;A号控制子程序入口 PB: … ;B号控制子程序入口 PC: … ;C号控制子程序入口 PD: … ;D号控制子程序入口

跳转表的组成 跳转指令(转向子程序的转移指令) 2. 利用跳转表实现分支 ——多用于多路分支 跳转地址(各子程序入口地址) 跳转表的组成 跳转指令(转向子程序的转移指令) (1)根据表内地址分支 ——将需要分支的各子程序入口地址按照一定的顺序存放在 内存区域中,在主程序中根据一定的算法计算出某子程 序地址在跳转表中的位置,从而得到相应子程序的入口 地址,然后用JMP指令转去执行。

Y N 结束 开始 AL←键盘输入字符 AL<41H? AL>44H? AL←AL-41H BX←取地址跳转表首址 AH←0 AL←计算表内地址 计算表地址BX←BX+AX 根据地址转向相应分支

(3)根据流程图编写汇编语言程序 ADATA SEGMENT BASE DW PA,PB,PC,PD KEY DB ? ADATA ENDS ASTACK SEGMENT PARA STACK ‘STACK’ DW 100 DUP(?) TOP LABEL WORD ASTACK ENDS ACODE SEGMENT ASSUME CS:ACODE,DS:ADATA,SS:ASTACK START:MOV AX,ASTACK MOV SS,AX MOV SP, OFFSET TOP

MOV AX, ADATA MOV DS, AX LOP: MOV AH,1 INT 21H CMP AL,41H JB LOP CMP AL,44H JA LOP SUB AL,41H MOV BX,OFFSET BASE MOV AH,0 ADD AL,AL ADD BX,AX JMP WORD PTR[BX] ACODE ENDS END START

三、循环结构程序设计 1. 循环程序的组成 循环程序是在满足某些条件时对一段程序的重复执行,一般由四部分组成。 2. 基本结构形式 (1) 先执行后判断(do—while) 至少进入一次循环体。常用于循环次数已知时。 (2) 先判断后执行 循环体可一次都不执行。常用于循环次数未知,根据具体情况找出控制循环体结束的条件时常用。

统计字节数据块:-1,-3,5,6,9,…中负元素的个数。 (1) 先执行后判断(do—while) 例:P173 统计字节数据块:-1,-3,5,6,9,…中负元素的个数。 数据段定义如下: DATA SEGMENT BUF DB -1,-3,5,6,9,… ;定义若干字节带符号数 CUNT EQU $-BUF ;计算数据块长度 RESULT DW ? ;定义存放结果单元 DATA ENDS DATA SEGMENT BUF DB -1,-3,5,6,9,… ;定义若干字节带符号数 CUNT EQU $-BUF ;计算数据块长度 RESULT DW ? ;定义存放结果单元 DATA ENDS 对应的代码段程序: MOV BX,OFFSET BUF ;建立数据指针 MOV CX,CUNT ;设置循环次数 MOV DX,0 ;置结果初值 LP1: MOV AL,[BX] ;取数据 AND AL,AL JNS PLUS ;是正数,转去PLUS INC DX ;是负数,负数个数+1 PLUS: INC BX ;调整数据指针 LOOP LP1 ;(CX-1)≠0,继续循环 MOV RESULT,DX ;存入负数个数

循环体可一次都不执行。在循环次数未知,需根据具体情况找出控制循环体结束的条件时常用。 (2) 先判断后执行 循环体可一次都不执行。在循环次数未知,需根据具体情况找出控制循环体结束的条件时常用。 例:P173 例5-6 AX寄存器中有一个16位的二进制数,编程统 计其中1的个数,结果存放在CX寄存器中。 控制循环体的条件是:当AX内容为全0,不必再继续统计。 程序如下: MOV CX,0 ;置结果计数器初值 LP: AND AX,AX ;AX=0否 JZ EXIT ;是,退出循环 SAL AX,1 ;否,AX的最高位移至CF中 JNC ZERO ;CF=0,转ZERO继续循环 INC CX ;CF=1,结果计数器加1 ZERO: JMP LP EXIT: :

3. 循环控制方法 每个循环程序必须选择一个循环控制条件,来控制循环的运行和结束。常用循环控制条件(方法): (1)计数控制——循环次数已知,每循环一次加/减1。 (2)条件控制——循环次数未知,须根据条件控制循环。 (3)逻辑尺控制——多次循环过程中分别做不同的操作时, 可通过建立位串(逻辑尺)控制循环。

子程序不是一种基本的程序结构,但在程序设计时合理使用子程序是实现模块化程序设计的重要技巧。有两种子程序: 子程序设计和调用技术 子程序不是一种基本的程序结构,但在程序设计时合理使用子程序是实现模块化程序设计的重要技巧。有两种子程序: ① 重复使用的程序段或具有通用性便于共享的程序段(键盘处理、代码转换); ② 中断处理子程序:中断处理随机产生,对其处理只能采用子程序的形式。 二、子程序设计中的问题 1. 主程序与子程序的连接 主、子程序都存放在代码段: CALL:断点保护,转子程序。 RET: 断点恢复 。 若主、子程序在同一代码段,为段内调用; 若主、子程序各在不同的代码段,为段间调用。

“现场”,指转向子过程执行时主过程的状态,主要包括当时标志寄存器、段寄存器、通用寄存器及指令指针的内容。 2. 现场的保护与恢复 “现场”,指转向子过程执行时主过程的状态,主要包括当时标志寄存器、段寄存器、通用寄存器及指令指针的内容。 为保证主、子过程各自的数据信息和工作状态不会互相干扰,设计程序时应尽量使主、子过程有属于自己的工作空间。 用成对的PUSH、POP指令保护主程序与子程序中都要用到的Reg及mem。 方法二: . PROC-1 PROC . PUSH BX . PUSH CX CALL PROC-1 . POP CX . POP BX . RET PROC-1 ENDP … 方法一: PUSH BX PUSH CX CALL PROC-1 POP CX POP BX 常用第二种方法保护和恢复现场。对中断子程序必须用第二种方法。

3. 主、子程序之间的参数传递 入、出口参数——传给子程序的参数及从子程序出来的参数。 参数传递通常有3种方法: (1)使用约定的寄存器传递 3. 主、子程序之间的参数传递 入、出口参数——传给子程序的参数及从子程序出来的参数。 参数传递通常有3种方法: (1)使用约定的寄存器传递 ——用寄存器实现参数传递。这也是最常用的方法,主要原因有寄存器是一种不用定义的全局寄存器变量、存取速度极快,但传递参数的个数有限。 (2)使用约定的存储单元传递 ——用内存变量实现参数传递。这种方法可以用于传递大量的参数,但其存取速度较慢。汇编语言中所定义的变量均为全局变量,无局部变量的概念。 (3)使用堆栈传递 ——这种方法容易引起错误,因为调用子程序时主程序的断点也在堆栈中,稍不留神就有可能使程序飞了。这种方法主要在多种语言混合编程时采用。

例1:求数组ARRAY中所有元素之和并存于SUM单元中。 三、子程序应用举例 (1) 使用约定的寄存器传递参数。 首先考虑如何编制一个子程序(确定算法); 在主、子程序中使用相同的寄存器。 例1:求数组ARRAY中所有元素之和并存于SUM单元中。 ;子程序名:SUM1。程序功能:求字节数组和。 ;入口参数:SI=数组首址,CX=数组长度 ;出口参数:AX=数组和。使用寄存器:AX,CX,SI。

STACK SEGMENT PARA STACK ‘STACK’ DB 100 DUP (?) STACK ENDS DATA SEGMENT ARRAY DB d1,d2,d3,…,dn ;若是字数组, COUNT EQU $-ARRAY ;个数= ($-ARRAY)/ 2 SUM DW ? DATA ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA START: MOV AX,DATA MOV DS,AX LEA SI,ARRAY MOV CX,COUNT CALL SUM1 ;调用子程序求和,返回值在AX中 MOV SUM,AX ;和存于SUM单元 MOV AH,4CH ;返回DOS INT 21H ;入口参数准备,将需要传递的 参数送入寄存器

SUM1 PROC NEAR CMP CX,0 JZ EXIT MOV AX,0 ;数组和通过AX寄存器回送到主程序 AGAIN: ADD AL,[SI] ADC AH,0 INC SI LOOP AGAIN EXIT: RET SUM1 ENDP CODE ENDS END START 请注意子程序与主程序都放在同一个代码段!

程序应用举例 例1:在某串中查找某个特定字符,找到显示‘Y’,未找到显示‘N’。 分析:在串中查找可用两种方法实现:串查找和循环比较。串查找方法的核心指令为REPNE SCASB,使用这条指令之前必须预置ES、DI、AL、DF、CX的初值。ES:DI指向待查字符串,CX为串长,AL存放待查字符,DF决定串指针DI的变化方向(一般为0即向加的方向变化)。循环比较方法的核心指令为比较指令及LOOPNE 标号,这里特别要注意LOOPNE所判断的ZF应为比较指令所影响的ZF。而非参数改变影响的ZF。

------------------------------------------------------------------ DATA SEGMENT STRING DB ‘How are you!, welcome to china!’ N EQU $-STRING DATA ENDS ------------------------------------------------------------------ CODE  SEGMENT ASSUME  CS:CODE,ES:DATA START:  MOV  AX,DATA  ;置ES段初值 MOV  ES,AX LEA DI,STRING MOV CX,N CLD MOV AH,1 INT 21H ;从键盘输入待查字符

REPNE SCASB JZ FOUND ;转到找到分支 MOV DL,‘N’ ;未找到处理 JMP DISP ;转到后续公共位置处 FOUND: MOV DL,‘Y’ DISP: MOV AH,2 INT 21H    MOV  AH,4CH  ;返回DOS      INT  21H ---------------------------------------------------------------------------------------------------------- CODE ENDS END  START

DATA SEGMENT STRING DB ‘How are you!, welcome to china!’ N EQU $-STRING DATA ENDS CODE  SEGMENT ASSUME CS:CODE,DS:DATA START: MOV AX,DATA  ;置ES段初值 MOV DS,AX LEA DI,STRING-1 ;置串指针初值,因为循环中参数改变需要置于比较指令之前,所以应先减1 MOV CX,N MOV AH,1 INT 21H

AGAIN: INC DI ;参数改变 CMP AL,[DI] ;比较查找 LOOPNE AGAIN ;未找到且没找完继续查找 JZ FOUND ;转到找到分支 MOV DL,‘N’ ;未找到处理 JMP DISP ;转到后续公共位置处 FOUND: MOV DL,‘Y’ DISP: MOV AH,2 INT 21H    MOV AH,4CH  ;返回DOS      INT  21H CODE ENDS END START

例2:求1至10的累加和送AL。 分析:循环操作为累加,和初值为0,参数初值为1,累加到10为止,即循环次数为10次,本例采用直到循环编程,下例采用当循环编程。 CODE  SEGMENT ASSUME CS:CODE START: MOV  CX,10 MOV  BL,1 XOR  AL,AL AGAIN:  ADD  AL,BL INC  BL LOOP AGAIN    MOV  AH,4CH INT  21H CODE  ENDS END  START

例3:对例2用当循环法编程 CODE SEGMENT ASSUME CS:CODE START: MOV BL,1 XOR AL,AL AGAIN: CMP BL,10 : CMP BL,11 JA DONE ; JZ DONE ADD AL,BL INC  BL JMP  AGAIN DONE: MOV AH,4CH INT  21H CODE  ENDS END START