本周实验安排 实验内容:(P231)人名排序的例子。

Slides:



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

汇编语言程序设计 吴 向 军 中山大学计算机科学系
微型计算机技术 教 学 指 导(七) 太原广播电视大学 郭建勇.
第10章 DOS功能调用与BIOS中断调用.
第7章 8086/8088汇编语言程序设计 7.1 引言 7.2 顺序程序设计 7.3 分支结构程序设计 7.4 循环结构程序设计
第四章 汇编语言 程序设计 任课教师:王晓甜
大连理工大学软件学院 软件工程系 赖晓晨 计算机组成与结构 大连理工大学软件学院 软件工程系 赖晓晨
输入/输出及接口 输入/输出的传送方式 中断技术 80x86/Pentium中断系统 8259A可编程中断控制器 中断程序设计
微机原理与接口技术 微机原理与接口技术 朱华贵 2015年10月30日.
第3章 80x86汇编语言程序设计(下).
第3章 80x86汇编语言程序设计(中) 时间不够的情况下只讲16位汇编.
第三章 指令系统及其寻址方式 3.1 寻址方式 3.2 指令格式 3.3 指令系统.
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日.
微机原理与接口技术 第3章 8086/8088指令系统 黄强 深圳大学 信息工程学院.
第5章 循环与分支程序设计  循环程序设计  分支程序设计.
汇编语言程序设计 Assembly Language Programming
第三章 寻址方式与指令系统 3.1 寻址方式 一条指令通常由两大部分构成: 操作码 操作数
微机原理与接口技术 第3章 8086指令系统 朱华贵 2015年09月25日.
第7章 并行接口 7.1 简单并行接口 7.2 可编程并行接口8255A 7.3 键盘接口 7.4 LED显示器接口.
第九章 计数器和定时器电路 第一节 概述 第二节 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设备.
第3章 IA-32指令系统 3.1 基本数据类型 3.2 IA-32的指令格式 3.3 IA-32指令的操作数寻址方式
汇编语言程序设计 吴 向 军 中山大学计算机科学系
第8章 寻址方式与指令系统.
第4章 汇编语言程序设计 4.1 程序设计语言概述 4.2 汇编语言的程序结构与语句格式 4.3 汇编语言的伪指令
微机原理及应用 主讲:谢维成 西华大学 电气信息学院 1.
基本的”防”黑客技术 Basic” ” Hacker Technique
微机原理及应用 主讲:郑海春.
第一章 8086程序设计 第二章 MCS-51程序设计 第三章 微机基本系统的设计 第四章 存贮器与接口 第五章 并行接口
第8章 PCH中的常规接口.
汇编语言程序设计课程设计 第二次实验 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中断调用
3.4.5 控制转移指令(Control transfer instructions) (一)、控制转移指令概述
微机原理与接口技术 微机原理与接口技术 朱华贵 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功能编写的程序简洁,可读性好,
《微型计算机原理与接口技术》 第4版 王良 宁德师范学院 吴宁 乔亚男 编著 清华大学出版社 出版
第5章 循环与分支程序设计  循环程序设计  分支程序设计.
微机原理与接口技术 微机原理与接口技术 朱华贵 2015年12月17日.
第八章 中断系统.
微机原理与接口技术 西安邮电大学计算机学院 宁晓菊.
虚拟机加密,是把源程序的X86指令变成自定义的伪指令,执行时内置在保护程序中的VM就会启动,读取伪指令,然后解析执行
微机原理与接口技术 微机原理与接口技术 朱华贵 2015年11月06日.
第3章 80x86的指令系统和寻址方式 § x86的寻址方式 § x86的指令系统
第6章 子程序结构 在程序设计中,我们会发现一些多次无规律重复的程序段或语句序列。解决此类问题一个行之有效的方法就是将它们设计成可供反复调用的独立的子程序结构,以便在需要时调用。在汇编语言中,子程序又称过程。 调用子程序的程序称为主调程序或主程序。 2019/7/20 ch6.
微机原理与接口技术 第5章 汇编语言程序设计 西安邮电大学计算机学院 王 钰.
大数据搜索挖掘实验室 第五章 子程序设计 张华平 副教授 博士 Website: 大数据搜索挖掘实验室
第4章 MCS-51汇编语言程序设计 教学基本要求: (1)、了解MCS-51汇编语言程序设计的特点;
第4章 汇编语言程序格式  汇编程序功能  伪操作  汇编语言程序格式  汇编语言程序的上机过程
第三章 8086的指令系统 8086指令特点 8086的寻址方式 8086的指令格式及数据类型 8086的指令集.
Presentation transcript:

本周实验安排 实验内容:(P231)人名排序的例子。 实验目的:1、掌握子程序的设计方法;2、 进 一步熟练debug的使用;3、掌握冒泡排序 实验要求:1、各子程序间是如何传递参数的? 又是如何相互调用的? 时间安排:本周五(5月13日)全天 2班 上午1、2节; 1班 上午3、4节 4班 下午1:45-3:15; 3班 下午3:15-4:45 返回本章首页

本次实验安排 实验内容:给定一组无符号字数,用冒泡排序按照 从大到小的顺序排序。 实验目的:1、掌握冒泡排序;2、 进一步熟练 debug的使用 实验要求:1、debug的8个基本命令都要用到;2、 在debug下能显示第一次排序后的结果 时间安排:本周五(4月22日)全天 2班 上午1、2节; 1班 上午3、4节 4班 下午1:45-3:15; 3班 下午3:15-4:45 返回本章首页

补充:汇编语言源程序的基本结构 数据段 附加数据段 堆栈段 代码段 END [标号] 说明: 1、各段顺序无关 2、除代码段外,其他都可缺省 3、数据段和代码段可有多个 附加数据段 堆栈段 代码段 END [标号]

最简单的汇编源程序 只有代码段的程序: code segment ;代码段定义 assume cs:code ;假定伪操作进行段匹配 start: ;第一条可执行指令的标号 mov ah,4ch int 21h ;此两条指令用于返回DOS系统 code ends ;代码段结束 end start ;汇编源程序结束

有数据段的源程序模板 data segment ;数据段定义 string db ‘hello world’,’$’ data ends ;数据段结束 code segment ;代码段定义 assume ds:data,cs:code main proc far ;主程序定义 start: ;第一条可执行指令的标号 mov ax,data mov ds,ax mov dx,offset string mov ah,09h int 21h mov ah,4ch main endp ;主程序结束 code ends ;代码段结束 end start ;汇编源程序结束

第5章 程序设计方法 5.1 概述 5.2 顺序程序设计 5.3 循环程序设计 5.4 分支程序设计 5.5 子程序设计 实验安排 开 始

5.1 概述 5.1.1 汇编语言程序设计的一般步骤 5.1.2 流程图 返回本章首页

5.1.1 汇编语言程序设计的一般步骤 汇编语言程序设计一般有以下几个步骤: 1.分析问题,确定算法 2.绘制流程图 3.根据流程图编制程序 5.1.1 汇编语言程序设计的一般步骤 汇编语言程序设计一般有以下几个步骤: 1.分析问题,确定算法 2.绘制流程图 3.根据流程图编制程序 4.调试程序 返回本节

5.1.2 流程图 1.流程图的概念 流程图是由特定的几何图形、指向线、文字说明 来表示数据处理的步骤,形象描述逻辑控制结构 以及数据流程的示意图。流程图具有简洁、明了、 直观的特点。 2.流程图符号表示 (1)起止框:表示程序 的开始和结束。 起止框

(2)判断框 (3)处理框 (4)调用框

(5)指向线 返回本节

5.2 顺序程序设计 下面举例说明顺序程序的设计。 【例5.1】试编写一程序计算以下表达式的值。 w=(v-(x*y+z-540))/x 5.2 顺序程序设计 下面举例说明顺序程序的设计。 【例5.1】试编写一程序计算以下表达式的值。 w=(v-(x*y+z-540))/x    式中x、y、z、v均为有符号字数据。 设x、y、z、v的值存放在字变量X、Y、Z、V中, 结果存放在双字变量W之中,程序的流程图如图5.1 所示。

图5.1 顺序运算程序流程图

源程序如下: DATA SEGMENT X DW 200 Y DW 100 Z DW 3000 V DW 10000 W DW 2 DUP(?) DATA ENDS STACK SEGMENT STACK DB 200 DUP(0) STACK ENDS CODE SEGMENT ASSUME DS:DATA,CS:CODE,SS:STACK

START: MOV AX,DATA MOV DS,AX ;DATA→AX MOV AX,X IMUL Y ;(X)*(Y)→DX:AX MOV CX,AX MOV BX,DX ;(DX:AX)→(BX:CX) MOV AX,Z CWD ;(Z)符号扩展 ADD CX,AX ADC BX,DX ;(BX:CX)+(DX:AX)→(BX:CX) SUB CX,540 SBB BX,0 ;(BX:CX)-540→(BX:CX) MOV AX,V

CWD ;(V)符号扩展 SUB AX,CX SBB DX,BX ;(DX:AX)-(BX:CX)→(DX: AX) IDIV X ;(DX:AX)/X MOV W,AX ;商→W MOV W+2,DX ;余数DX→W+2 MOV AH,4CH INT 21H ;返回DOS 状态 CODE ENDS END START

【例5.2】 【例5.2】已知某班学生的英语成绩按学号(从 1开始)从小到大的顺序排列在TAB表中,要 查的学生的学号放在变量NO中,查表结果放 在变量ENGLISH中。编写程序如下:

STACK SEGMENT STACK DB 200 DUP(0) STACK ENDS DATA SEGMENT TAB DB 80,85,86,71,79,96 DB 83,56,32,66,78,84 NO DB 10 ENGLIST DB ? DATA ENDS CODE SEGMENT

返回本章首页 ASSUME DS:DATA,SS:STACK,CS:CODE BEGIN: MOV AX,DATA MOV DS ,AX LEA BX,TAB ;把所要查表的首地址付给BX寄存器 MOV AL,NO DEC AL ;学号从1开始,但tab的偏移地址从0开始的,故AL要减1 XLAT TAB ;换码指令,课本55页 MOV ENGLISH,AL ;换码后的结果送入ENGLISH内存变量 MOV AH,4CH INT 21H ;返回DOS系统 CODE ENDS ;代码段结束 END BEGIN ;源程序结束 返回本章首页

5.3 循环程序设计 5.3.1 循环程序的结构 5.3.2 单重循环程序设计 5.3.3 多重循环程序设计 返回本章首页

5.3.1 循环程序的结构 1.初始化部分 2.循环体部分 3.循环控制部分

循环程序的常见结构形式如图4.5(a)、(b)所示。 返回本节

5.3.2 单重循环程序设计 1.计数控制 2.条件控制

1.计数控制 【例5.3】已知有几个元素存放在以BUF为首址 的字节存贮区中,试统计其中正元素的个数。 显然,每个元素为一个8位有符号二进制数, 统计其中正元素的个数可用循环程序实现。 其程序流程图如图5.2所示。

图5.2 程序流程图

【例5.4】 【例5.4】试编写一程序把BX寄存器内的二进 制数用十六进制数的形式在屏幕上显示出来。 思路: 其流程图如图5.3所示。 循环移位的方法; 数字0-9的ASCII与字母A-F的ASCII有区别,故要进行一次判断 其流程图如图5.3所示。

图5.3 程序流程图

【程序如下:】 CODE SEGMENT ASSUME CS:CODE MAIN PROC FAR START: MOV CH,4 ;循环次数 ROTATE: MOV CL,4 ROL BX,CL MOV AL,BL AND AL,0FH ;BL的高四位清0 ADD AL,30H CMP AL,3AH JL PRINTIT ADD AL,7H

PRINTIT: MOV DL,AL MOV AH,2 INT 21H ;2号系统功能调用,输出一个字符 DEC CH JNZ ROTATE MAIN ENDP CODE ENDS END START

2.条件控制 【例5.5】试编一个程序将字单元BUF中所含1的 个数存入COUNT单元中。要测出BUF字单元所 含1的个数,首先将BUF中的数送给寄存器AX, 然后将AX寄存器逻辑左移一次,如果CF=1, 则表明AX中的最高位为1,则计数器CL计数1 次,如果CF=0,表明AX最高位为0,这样依次 将最高位移入CF中去测试。移位之后,判断 AX的值是否为0,如果为0则结束循环,不为0, 则继续循环。 其流程图如下图5.4所示。

图5.4 程序流程图

程序如下: STACK SEGMENT STACK DB 200 DUP(0) STACK EDNS DATA SEGMENT BUF DW 0011110010101011B COUNT DB ? DATA ENDS CODE SEGMENT ASSUME DS:DATA,CS:CODE,SS:STACK

START: MOV AX,DATA MOV DS,AX ;DATA->DS MOV AX,BUF MOV CL,0 ;计数器为0 LOPA: AND AX,0FFFFH JE EXIT ;(AX)=0,结束循环 SHL AX,1 ;AX 左移一位 JNC LOPA INC CL ;产生进位,(CL)+1→CL JMP LOPA EXIT: MOV COUNT,CL MOV AH,4CH INT 21H CODE ENDS END START

P164 【例5.3】 返回本节

5.3.3 多重循环程序设计 【例5.6】在以BUF为首址的字存储区中存放有N个有符 号数,现需将它们按大到小的顺序排列在BUF存储区 中,试编写其程序。 我们采用冒泡排序算法从第一个数开始依次对相邻 两个数进行比较,如次序对,则不交换两数位置; 如次序不对则使这两个数交换位置。可以看出,第 一遍需比较(N-1)次,此时,最小的数已经放到了 最后;第二遍比较只需考虑剩下的(N-1)个数,即 只需比较(N-2)次;第三遍只需比较(N-3) 次,……整个排序过程最多需(N-1)遍。如下面的 4个数即是采用冒泡排序比较的例子。

数 10 8 16 90 32 第一遍 10 16 90 32 8 第二遍 16 90 32 10 8 第三遍 90 32 16 10 8 程序流程图如图5.5所示。

图5.5 程序流程图

程序如下: DATA SEGMENT BUF DW 3,-4,6,7,9,2,0,-8,-9,-10,20 N=($-BUF)/2 DATA ENDS STACK SEGNMENT STACK DB 200 DUP(0) STACK ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA,SS:STACK

START: MOV AX,DATA MOV DS,AX MOV CX,N DEC CX LOOP1: MOV DX,CX ;外层循环 MOV BX,0 LOOP2: MOV AX,BUF[BX] ;内层循环 CMP AX,BUF[BX+2] JGE L XCHG AX,BUF[BX+2] MOV BUF[BX],AX

L: ADD BX,2 DEC CX JNE LOOP2 MOV CX,DX LOOP LOOP1 MOV AH,4CH INT 21H CODE ENDS END START

若要对N个无符号数按由大到小的顺序排列, 只需将指令“JGE L”改为“JAE L”即可。 程序运行后,BUF区中的内容如下: 20,9,7,6,3,2,0,-4,-8,-9,-10 若要对N个无符号数按由大到小的顺序排列, 只需将指令“JGE L”改为“JAE L”即可。 返回本节

5.4 分支程序设计 5.4.1 分支程序的结构形式 5.4.2 用条件转移指令实现程序分支 5.4.3 用跳转表实现多路分支 返回本章首页

分支程序的两种形式 1、IF_THEN_ELSE结构 2、CASE结构

5.4.2 用条件转移指令实现程序分支 【例5.7】编写计算下面函数值的程序: 1 X>0 Y= 0 X=0 -1 X 5.4.2 用条件转移指令实现程序分支 【例5.7】编写计算下面函数值的程序: 1 X>0 Y= 0 X=0 -1 X 设输入数据为X、输出数据Y,且皆为字节变量。程序 流程图如图5.6所示。 程序如下:

DATA SEGMENT X DB -10 Y DB ? DATA ENDS STACK SEGMENT STACK DB 200 DUP(0) STACK ENDS CODE SEGMENT ASSUME DS:DATA,SS:STACK,CS:CODE START: MOV AX,DATA

MOV DS,AX CMP X,0 ;与0进行比较 JGE A1 ;X≥0转A1 MOV Y,-1 ;X <0时,-1→Y JMP EXIT A1: JG A2 ;X>0转A2 MOV Y,0 ;X=0时,0→Y A2: MOV Y,1 ;X>0,1→Y EXIT: MOV AH,4CH INT 21H CODE ENDS END START

图5.6 分支运算程序流程图

【例5.8】 【例5.8】试编一程序,求三个带符号字数 据中的最大值,并将最大值存入MAX字单 元中。 设三个带符号数分别在三个字变量X、Y、 Z中存储。程序流程图如图5.7所示

图5.7 [例5.8]程序流程图

程序如下: STAC SEGMENT STACK DB 200 DUP(0) STACK ENDS DATA SEGMENT X DW 00ABH Y DW –5 Z DW 200 MAX DW ? DATA ENDS CODE SEGMENT

ASSUME DS:DATA,SS:STACK,CS:CODE START: MOV AX,DATA MOV DS,AX MOV AX,X CMP AX,Y ;X>Y? JG L1 MOV AX,Y ;Y>Z? CMP AX,Z JG EXIT L2: MOV AX,Z JMP EXIT

L1: CMP AX,Z ;X>Z? JLE L2 EXIT: MOV MAX,AX MOV AH,4CH INT 21H CODE ENDS END START 返回本节

5.4.3 用跳转表实现多路分支 【例5.9】设某程序有8路分支,试根据给定的 N值(1~8),将程序的执行转移到其中的一 路分支。 5.4.3 用跳转表实现多路分支 【例5.9】设某程序有8路分支,试根据给定的 N值(1~8),将程序的执行转移到其中的一 路分支。 程序流程如图5.8所示。 实际用的是DW定义地址的功能。

图5.8 [例5.9]程序流程图

程序如下: DATA SEGMENT TAB DW P1,P2,P3,P4,P5,P6,P7,P8 N DB 5 DATA ENDS STACK SEGMENT DB 200 DUP(0) STACK ENDS CODE SEGMENT ASSUME DS:DATA,SS:STACK,CS:CODE

START: MOV AX,DATA MOV DS,AX ┆ MOV AL,N DEC AL ADD AL,AL ;相当于N×2,因为是字变量 MOV BL,AL MOV BH,0 JMP TAB[BX]

P1: …… ┆ JMP EXIT P2: …… P3: ……

JMP EXIT ┆ P8: …… EXIT: MOV AH,4CH INT 21H CODE ENDS END START 上述程序中的无条件转移指令的转移地址采用的 是寄存器相对寻址。同理,转移地址也可以用寄存器 间接寻址或基址加变址寻址,读者可自行考虑。 返回本节

实验安排 实验内容:P194 5.23 时间:5月8日 全天 1班 上午1、2节; 2班 上午3、4节 1班 上午1、2节; 2班 上午3、4节 3班 下午1:45-3:15; 4班 下午3:15-4:45

5.5 子程序设计 5.5.1 子程序的概念 5.5.2 子程序的定义 5.5.3 子程序设计方法 5.5.4 子程序应用举例 5.5 子程序设计 5.5.1 子程序的概念 5.5.2 子程序的定义 5.5.3 子程序设计方法 5.5.4 子程序应用举例 5.5.5 子程序的嵌套与递归调用 返回本章首页

5.5.1 子程序的概念 在程序设计中,我们会发现一些多次无规律 重复的程序段或语句序列。解决此类问题一 个行之有效的方法就是将它们设计成可供反 复调用的独立的子程序结构,以便在需要时 调用。在汇编语言中,子程序又称过程。 调用子程序的程序称为主调程序或主程序。 返回本节

5.5.2 子程序的定义 子程序的定义是由过程定义伪指令PROC和ENDP来完成的。 其格式如下: 过程名 PROC [NEAR/FAR] 5.5.2 子程序的定义 子程序的定义是由过程定义伪指令PROC和ENDP来完成的。 其格式如下: 过程名 PROC [NEAR/FAR] ┆ 过程名 ENDP 其中PROC表示过程定义开始,ENDP表示过程定义结束。 过程名是过程入口地址的符号表示。 一般过程名同标号一样,具有三种属性,即段属性、偏 移地址属性以及类型属性。 返回本节

5.5.3 子程序设计方法 1.子程序的调用和返回 2.信息的保护与恢复 3.子程序的参数传送

1.子程序的调用和返回 CALL和RET指令完成的就是调用和返回的 功能。因此为保证正确性,还要注意子程序 运行期间的堆栈状态,即SP指针的位置。

2.信息的保护与恢复 例如:若子程序PROG中改变了寄存器AX,BX,CX, DX的值,则可采用如下方法保护和恢复 现场。 PROG PROC PUSH AX PUSH BX PUSH CX ;保护现场 PUSH DX ┆

┆ POP DX POP CX POP BX ;恢复现场 POP AX RET ;返回断点处 PROC ENDP

3.子程序的参数传送 (1)通过寄存器传递参数 (2)直接访问变量 (3)通过地址表传递参数地址 (4)堆栈法 (5)多个模块之间的参数传送问题 返回本节

(1)通过寄存器传递参数 优点:使用方便,比较常用 缺点:参数很多时不宜使用此种方法。 【例】十进制数到十六进制数的转换。要求从 键盘取得一个十进制数,然后把该数以16进 制的形式在屏幕上显示出来。 分析:用子程序结构;使用BX寄存器在过程 间传递要转换的数。

程序结构:

十进制数转换为二进制数的思路 键盘输入的是字符,因 此要一位一位的转换为 数字。如:输入‘12’, 则是1 ×10+2 因此,假设4位十进制数 从高位到低位依次为: d3,d2,d1,d0,则可用下 列多项式来计算值: (((0×10+d3) ×10+d2) ×10+d1) ×10+d0

程序如下: CODE SEGMENT ASSUME CS:CODE MAIN PROC FAR call decibin call crlf call binihex mov ah,4ch int 21h MAIN ENDP

DECIBIN PROC mov bx,0 newchar: mov ah,1 int 21h sub al,30h jl exit 十进制数转换为二进制数的子程序 DECIBIN PROC mov bx,0 newchar: mov ah,1 int 21h sub al,30h jl exit cmp al,9d jg exit cbw xchg ax,bx mov cx,10d mul cx add bx,ax jmp newchar exit: ret DECIBIN ENDP

BINIHEX ENDP BINIHEX PROC mov ch,4 ROTATE: MOV CL,4 ROL BX,CL MOV AL,BL AND AL,0FH ADD AL,30H CMP AL,3AH JL PRINTIT ADD AL,7H PRINTIT: MOV DL,AL MOV AH,2 INT 21H DEC CH JNZ ROTATE ret BINIHEX ENDP

CODE ENDS END MAIN CRLF PROC mov dl,0dh mov ah,02h int 21h mov dl,0ah 显示回车换行符的子程序 CRLF PROC mov dl,0dh mov ah,02h int 21h mov dl,0ah ret CRLF ENDP CODE ENDS END MAIN 返回

(2)直接访问变量 如果子程序(过程)和调用程序在同一源文件 (同一程序模块)中,则子程序(过程)可直 接访问模块中的变量。 P202【例6.4 】主程序MAIN和过程PROADD 在同一源文件中,要求用过程PROADD累加 数组中的所有元素,并把和送到指定的存储单 元中去。 返回

(3)通过地址表传递参数地址 在主程序中建立一个地址表,把要传送给子程序 的参数的地址都存放在地址表中,然后把地址 表的首地址通过寄存器BX传送到子程序中去。 P202【例6.4 】主程序MAIN和过程PROADD 在同一源文件中,要求用过程PROADD累加数 组中的所有元素,并把和送到指定的存储单元 中去。 源程序如下:

通过地址表传递参数的程序: DSEG SEGMENT ;数据段定义 ary dw 10 dup(3) count dw 10 sum dw ? table dw 3 dup(?) ;要传送3个字参数,因此定义3个字的内存空间 DSEG ENDS ;数据段结束

CSEG SEGMENT assume cs:CSEG, ds:DSEG, es:ESEG, ss:SSEG MAIN PROC ;主程序入口 mov ax, dseg ;数据段首地址给DS mov ds, ax mov table,offset ary ;把ary、count、sum的地址给 mov table+2,offset count 参数table mov table+4,offset sum mov bx,offset table ;把table的首地址给BX call proadd ;调用子程序proadd mov ax, 4c00h ;程序结束,返回到操作系统 int 21h MAIN ENDP ;主程序结束

proadd proc ;定义子程序 push ax ;保存寄存器 push cx push si push di mov si,[bx] ;ary的偏移地址给SI mov di,[bx+2] ;count的地址给DI mov cx,[di] ;count的值给CX mov di,[bx+4] ;sum的地址给DI xor ax,ax ;AX清0

next: add ax,[si] ;arry数组中的元素循环累加, add si,2 ;并把累加结果放到AX中 loop next mov [di],ax ;把累加结果回送到count内存单元中 pop di ;恢复寄存器的值 pop si pop cx pop ax ret proadd endp ; 子程序结束 CSEG ENDS ;代码段结束 END MAIN ;汇编语言源程序结束 返回

(4)堆栈法 在主程序里把参数地址保存到堆栈中,在子 程序里从堆栈中取出参数以达到传送参数的 目的。 例6.4 ex6-4s.doc

例6.4用堆栈传递参数地址时,堆栈最满时的状态 返回地址 例6.4用堆栈传递参数地址时,堆栈最满时的状态 返回

多个模块间的参数传送 外部符号: 从连接的角度看,源程序中用户定义的符号 可分为局部符号和外部符号。在本模块中定 义并在本模块中引用的符号称为局部符号; 而在一个模块中定义,又在另一个模块中引 用的符号称为外部符号。有两个伪操作与外 部符号有关:

Public伪操作,格式: public symbol[,…] 在一个模块中定义的符号(包括变量、标号、过程名等)在提 供给其他模块使用时,必须要用public定义该符号为外部符号。 Extrn伪操作,格式: extrn symbol name:type[,…] 在另一个模块中定义而要在本模块中使用的符号必须使用extrn 伪操作。如果符号为变量,则类型type为byte、word、dword 等;如果符号为标号或过程名,则类型为near或far。 注意:这两个伪操作的使用必须相匹配。连接程序会检查每个 模块中的extrn语句中的每个符号是否能和其相连接的其他模 块中的public语句中的一个符号相匹配。不匹配则会给出出错 信息。

例: ;MOD1.ASM EXTRN PROADD:FAR DATA SEGMENT … DATA ENDS CODE1 SEGMENT COMMON MAIN PROC FAR MAIN ENDP CODE1 ENDS END MAIN ;MOD2.ASM PUBLIC PROADD DATA SEGMENT … DATA ENDS CODE2 SEGMENT COMMON PROADD PROC FAR PROADD ENDP CODE1 ENDS END PROADD 返回

5.5.4 子程序应用举例 【例一】将一个给定的二进制数按位转换成相应 的ASCII码字符串,送到指定的存储单元并显示。 如二进制数10010011转换成字符串为 ‘10010011’。要求将转换过程写成子程序, 且子程序应具有较好的通用性,而必须能实现 对8倍和16倍二进制数的转换。

入口参数:DX存放待转换的二进制数 CX存放待转换数的位数(8位或16位) DI存放ASCII码首地址 出口参数:转换后的字符串存放在以DI作指针的字节存贮区中 程序如下: DATA SEGMENT NUM8 DB 93H NUM16 DW 0ABCDH ASCBUF DB 20 DUP(0) DATA ENDS

CODE SEGMENT ASSUME DS:DATA,CS:CODE, SS:STACK START: MOV AX,DATA MOV DS,AX MOV DX,0 MOV DL,NUM8 ;转换二进制数送DX MOV CX,8 ;置位数8 LEA DI,ASCBUF ;字符串首址→DI CALL BTASC ;调用子程序BTASC MOV [DI],BYTE PTR 0DH ;给ASCBUF字符串 MOV [DI+1],BYTE PTR 0AH ;增加结束符 MOV [DI+2],BYTE PTR ‘$’

LEA DX,ASCBUF MOV AH,9 ;显示转换后的字符串 INT 21H MOV DX,NUM16 MOV CX,16 ;置位数16 LEA DI,ASCBUF CALL BTASC MOV [DI],BYTE PTR 0DH MOV [DI+1],BYTE PTR 0AH MOV [DI+2],BYTE PTR ‘$’ ; 显示转换后的字符串 LEA DX, ASCBUF MOV AH,9

BTASC PROC PUSH AX ;保存AX MOV AL,0 CMP CX,8 ;比较8位数 JNE L1 ;直接转换16位数 MOV DH,DL ;8位数转换送DH L1: ROL DX,1 ;DX最高位移入CF RCL AL,1 ;CF移入AL最低位 ADD AL,30H MOV [DI],AL

INC DI LOOP L1 POP AX RET BTASC ENDP CODE ENDS END START

【例二】人名排序P231 程序框图如右图所示: 返回本节 B10READ:接收键入的人名存放在namepar缓冲区中,并用空格符清除其后的单元。 D10STOR:把人名从NAMEPAR传送到NAMETAB中,并用NAMECTR计数。 G10STOR:用气泡排序算法对人名排序,并用swapped作为交换标志控制循环的结束。其中调用H10XCHG来交换两个人名串的位置,并设置swapped标志。 K10DISP:显示已排序了的人名。 返回本节

5.5.5 子程序的嵌套与递归调用 1.子程序的嵌套 子程序不但可以被主程序调用,而且也可以被其他 子程序调用。我们把一个子程序调用另一个子程序 称为子程序的嵌套调用。 2.子程序的递归调用 子程序的递归调用是指一个子程序直接或间接地调用 自己。递归子程序一般对应于数学上对函数的递归 定义,它往往能设计出效率较高的程序,完成相当 复杂的计算,因而是很有用的。

【例5.11】 【例5.11】试编制计算N! (N≥0)的程序。N!=N*(N- 1)*(N-2)*……*1 其递归定义如下: 0!=1 计算N!的子程序FACT的流程图如图5.10所示。

【例5.11】计算5!的程序示例, RESULT是保存阶乘的存储单元。 程序如下: STACK SEGMENT STACK DB 200 DUP(0) STACK ENDS DATA SEGMENT N DW 5 RESULT DW ? DATA ENDS CODE SEGMENT ASSUME CS:CODE, SS:STACK,DS:DATA

START: MOV AX,DATA MOV DS,AX MOV AX,N CALL FACT MOV AX,RESULT MOV AH,4CH INT 21H FACT PROC CMP AX,0 JNE L1

返回本节 MOV RESULT,1 JMP EXIT L1: PUSH AX DEC AX CALL FACT POP AX MUL RESULT MOV RESULT,AX EXIT: RET FACT ENDP CODE ENDS END START 返回本节

Thank you very much ! 本章到此结束,谢谢您的光临 ! 结 束 返回本章首页