第6章 汇编语言程序设计

108
第6第 第第第第第第第第 6.1 汇汇汇汇汇汇汇汇汇汇 汇汇汇汇汇汇汇汇汇汇汇汇 汇汇汇汇汇汇汇汇汇汇汇 :一 EXE 汇汇汇汇汇汇 汇汇 EXE 汇汇汇汇汇汇汇 汇汇 汇汇汇汇汇汇汇汇汇汇汇 ;一 COM 汇汇汇汇汇汇 汇汇 COM 汇汇汇汇 汇汇汇6.1.1 EXE 汇汇汇汇汇汇汇 EXE 汇汇汇汇汇汇汇汇汇汇汇汇汇汇汇汇汇汇汇 汇汇汇汇汇汇 汇汇汇汇汇汇汇汇汇汇 ,, 汇汇 64KB 汇汇汇汇汇汇汇汇汇

description

第6章 汇编语言程序设计. 6.1汇编源程序的编程格式 汇编源程序有两种编程格式:一种格式只能生成扩展名为 EXE 的可执行文件,称为 EXE 文件的编程格式;另一种格式可以生成扩展名为 COM 的可执行文件,称为 COM 文件的编程格式。 6.1.1 EXE 文件的编程格式 EXE 文件的编程格式允许源程序使用多个逻辑段,在实模式下,每个逻辑段的目标块不超过64 KB, 适合于编写大型程序。. 开 始. 6.1.2 COM 文件的编程格式 COM 文件的编程格式必须必须符合以下规定: (1)源程序只允许使用一个逻辑段,即代码段,不允许设置堆栈段; - PowerPoint PPT Presentation

Transcript of 第6章 汇编语言程序设计

Page 1: 第6章  汇编语言程序设计

第 6 章 汇编语言程序设计

6.1 汇编源程序的编程格式 汇编源程序有两种编程格式:一种格式只能生成扩展名为

EXE 的可执行文件,称为 EXE 文件的编程格式;另一种格式可以生成扩展名为 COM 的可执行文件,称为 COM文件的编程格式。

6.1.1 EXE 文件的编程格式 EXE 文件的编程格式允许源程序使用多个逻辑段,在实模

式下,每个逻辑段的目标块不超过 64KB ,适合于编写大型程序。

开 始

Page 2: 第6章  汇编语言程序设计

6.1.2 COM 文件的编程格式

COM 文件的编程格式必须必须符合以下规定:

( 1 )源程序只允许使用一个逻辑段,即代码段,不允许设置堆栈段;

( 2 )程序使用的数据,可以集中设置在代码段的开始或末尾;

( 3) 在代码段偏移地址(有效地址)为 100H 的单元,必须是程序的启动指令;

( 4 )代码段目标小于 64KB 。

Page 3: 第6章  汇编语言程序设计

6.1.3 EXE 文件和 COM 文件的内存映像

EXE 文件包括两部分:一部分为装入模块,另一部分为“重定位信息”。调入后生成 PSP (程序段前缀)

DOS 自动给 DS , ES , FS 和 GS 赋值,使 DS=ES= 存放PSP 的段基址, FS=GS=0, 并使 CS : IP =用户程序的启动 地 址 , SS : SP 指 向 用 户 堆 栈 段 的 栈 顶 , 在 这 以后, DOS 才把控制权交给用户程序。

COM 文件没有重定位信息,因此比 EXE 文件的体积小的多。 DOS 装载 COM 文件时,也生成 PSP ,然后从偏移地址 100H 开始依次存放用户程序。 DOS 自动赋值使CS=DS=ES=SS=PSP 段 基 址 , FS=GS=0 , 并 使IP=100H , SP=FFFEH 。

Page 4: 第6章  汇编语言程序设计

6.1.4 程序段前缀

6.1.5 返回 DOS 的其他方法

对于 COM 文件有三种方法:

( 1 )直接执行 INT20H ;

( 2 )调用 INT21H 的 0 号功能。

( 3 )执行 RET 指令

Page 5: 第6章  汇编语言程序设计

对于 EXE 文件:

( 1 )调用 INT 21H 的 4CH 功能

( 2 )执行 INT 20H ,首先把执行过程包含在一个远过程中;

其次在给 DS 赋值前,用 3 条指令把 PSP 首单元的物理地址压入栈顶,即: PUSH DS MOV AX,0 PUSH AX ,最后程序在需要返回 DOS 的地方执行一条 RET 指令。

6.1.6 源程序堆栈段的设置

Page 6: 第6章  汇编语言程序设计

对 8086 系列机来说, MS-DOS 操作系统是最主要的操作系统。 MS-DOS 操作系统除了具有较为完整的文件管理功能之外,同时还为各种应用程序、外围设备等提供软件接口。它由三部分组成:IO.SYS 、 MSDOS.SYS 以及 COMMAND.COM 。DOS 系统功能调用的方法一般可分为以下几步:① 设置所要调用功能的入口参数。② 在 AH 寄存器中存入所要调用功能的功能号。③ INT 21H 指令自动转入中断子程序入口。④ 相应中断子程序运行完毕,可按规定取得出口参数。

返回本节

6.2 DOS 系统功能调用

Page 7: 第6章  汇编语言程序设计

6.2 常用的 DOS 系统功能调用 1 .单字符输入( 1 号调用) 2 .单字符显示( 2 号调用) 3 .打印输出( 5 号调用) 4 .结束调用( 4CH号调用) 5 .显示字符串( 9 号调用) 6 .字符串输入( 10 号调用)

Page 8: 第6章  汇编语言程序设计

1 .单字符输入( 1 号调用)格式: MOV AH , 1 INT 21H功能:从键盘输入字符的 ASCII 码送入寄存器AL 中,并送显示器显示。 2 .单字符显示( 2 号调用)格式: MOV DL ,待显示字符的 ASCII 码 MOV AH , 2 INT 21H功能:将 DL 寄存器中的字符送显示器显示,如果 DL 中为〈 CTRL 〉 + 〈 BREAK 〉的 ASCII码,则退出。

Page 9: 第6章  汇编语言程序设计

3 .打印输出( 5 号调用) 格式: MOV DL ,待打印字符的 ASCII 码 MOV AH , 5 INT 21H 功能:将 DL 寄存器中的字符送打印机打印。 4 .结束调用( 4CH 号调用) 格式: MOV AH , 4CH INT 21H 功能:终止当前程序并返回调用程序。

Page 10: 第6章  汇编语言程序设计

5 .显示字符串( 9 号调用) 格式: LEA DX ,待显示字符串首偏移地址 MOV AH , 9 INT21H 功能:将当前数据区中以‘$’结尾的字符串送显示

器显示。 6 .字符串输入( 10 号调用) 格式: LEA DX ,缓冲区首偏移地址 MOV AH , 10 INT 21H 功能:从键盘上输入一字符串到用户定义的输入缓冲区中,并送显示器显示。

Page 11: 第6章  汇编语言程序设计

DATA SEGMENTSTR DB 0DH , 0AH ‘, Example of string display ’!$DATA ENDSSTACK SEGMENT STACKDB 100 DUP ( 0 )STACK ENDSCODE SEGMENT ASSUME DS : DATA , CS :CODE , SS : STACK

【例 3.25 】若要在屏幕上显示字符串“ Example of string display ”! ,则程序如下:

Page 12: 第6章  汇编语言程序设计

BEGIN : MOVAX , DATA

MOV DS , AX LEA DX , STR MOV AH , 9 INT 21H MOV AH , 4CH INT 21H CODE ENDS END BEGIN

返回本节

Page 13: 第6章  汇编语言程序设计

综合举例【例 3.27 】已知一数据段中的数据为:DATA SEGMENTA DW MBUFDB ‘AB’ , 0DH , 0AHC EQU 500HB DW 0FFAAHD DD BUFM DB 2DUP ( 1 ) , 2DUP ( 2 ’, B’ )DATA ENDS请画出该数据段数据存储的形式。 返回本章首页

Page 14: 第6章  汇编语言程序设计

该数据段在主存中的存储形

式如左图所示。

Page 15: 第6章  汇编语言程序设计

DATA SEGMENTNUM DB 01000101BBUFDB 0DH , 0AH ‘, ( NUM ) =’STR DB 4 DUP (?)DATA ENDSSTACK SEGMENT STACK DB 200 DUP ( 0 )STACK ENDSCODE SEGMENTASSUME DS : DATA , SS : STACK , CS :CODE

【例 3.28 】阅读下列程序,指出此程序所完成的功能以及在显示器上显示的内容。

Page 16: 第6章  汇编语言程序设计

START : MOV AX , DATA MOV DS , AX LEA DI , STR MOV AL , NUM MOV CL , 4 SHR AL , CL OR AL , 30H MOV [DI] , AL INC DI MOV AL , NUM AND AL , 0FH OR AL , 30H MOV [DI] , AL

Page 17: 第6章  汇编语言程序设计

INC DI MOV BYTEPTR [DI] ‘, H’ INC DI MOV BYTEPTR [DI] ‘ ’, $ LEA DX , BUF MOV AH , 9 INT 21H MOV AH , 4CH INT 21HCODE ENDS END START

Page 18: 第6章  汇编语言程序设计

DATA SEGMENTINFO1 DB 0DH , 0AH ‘, INPUT STRING ’:$INFO2 DB 0DH , 0AH ‘, OUTPUT STRING ’:$BUFA DB 81 DB ?

【例 3.29 】从键盘上输入一串字符到输入缓冲区,然后将输入的字符串在显示器上以相反的顺序显示。

Page 19: 第6章  汇编语言程序设计

DB 80 DUP ( 0 )BUFB DB 81 DUP ( 0 )DATA ENDSSTACK SEGMENT DB 200 DUP ( 0 )STACK ENDSCODE SEGMENT ASSUME DS : DATA , SS :STACK , CS : CODESTART : MOV AX , DATA MOV DS , AX

Page 20: 第6章  汇编语言程序设计

LEA DX , INFO1 MOV AH , 9 ; 9 号调用,显示输入提示信息 INT 21H LEA DX , BUFA MOV AH , 10 ; 10 号调用,键盘输入字符串到缓 冲区 BUFA INT 21H LEA SI , BUFA+1 MOV CH , 0 ; 取字符长度→ CX MOV CL , [SI] ADD SI , CX ; SI 指向字符串尾部 LEA DI , BUFB ; DI 指向字符串变量 BUFB

Page 21: 第6章  汇编语言程序设计

NEXT : MOV AL , [SI] MOV [DI] , AL DEC SI INC DI LOOP NEXT MOV BYTE PTR [DI] ‘ ’, $ LEA DX , INFO2 MOV AH , 9 ; 9 号调用,显示

输出 提示信息 INT 21H

Page 22: 第6章  汇编语言程序设计

LEA DX , BUFB MOV AH , 9 ;反向显示字

符串 INT 21H MOV AH , 4CH INT 21H CODE ENDS ENDSTART

返回本节

Page 23: 第6章  汇编语言程序设计

6.3 BIOS 键盘输入功能调用调用模式:

MOV AH, 功能号设置入口参数INT n

分析出口参数BIOS 键盘输入功能使用 INT 16H

1 功能号 00H :读取键入的一个字符,无回显,响应CTRL_C ,无键入则等待。

入口参数:无出口参数: AL= 输入字符的 ASCII 码2 功能号 01H :查询键盘缓冲区入口参数:无出口参数: Z=0 ,表示有键入,否则无键入

Page 24: 第6章  汇编语言程序设计

3 功能号 02H :读取当前转换状态入口参数:无出口参数: AL= 键盘状态字( P94 )4 功能号 10H :读扩展键盘,无回显,响应 CTRL_C 。入口参数:无出口参数:同 00H

5 功能号 11H :查询键盘缓冲区6 功能号 12H :读取扩展键盘的转换状态。

Page 25: 第6章  汇编语言程序设计

6.4 文本方式 BIOS屏幕功能调用6.4.1 显示器6.4.2 文本方式 BIOS屏幕调用调用指令 INT 10H

1 功能号 00H :设置屏幕显示方式2 功能号 01H :设置光标形状3 功能号 02H :预置光标位置4 功能号 03H :读取光标的当前位置5 功能号 05H :设置当前显示页6 功能号 06H :窗口上滚7 功能号 07H :窗口下滚8 功能号 08H :读取光标所在位置的字符及其属性9 功能号 09H :从光标所在位置开始,显示若干个相同的字

Page 26: 第6章  汇编语言程序设计

10 功能号 0AH :从光标所在位置开始,显示若干个相同的字符

11 功能号 0EH :显示一个字符12 功能号 13H :显示字符串

Page 27: 第6章  汇编语言程序设计

6.5 程序设计方法 1 概述 2 顺序程序设计 3 分支程序设计 4 循环程序设计 5 子程序设计 6 模块化程序设计 7 高级汇编语言技术

开 始

Page 28: 第6章  汇编语言程序设计

1 概述

(1) 汇编语言程序设计的一般步骤

(2) 流程图

返回本章首页

程序设计方法

Page 29: 第6章  汇编语言程序设计

汇编语言程序设计的一般步骤

汇编语言程序设计一般有以下几个步骤:

1 .分析问题,确定算法2 .绘制流程图3 .根据流程图编制程序4 .调试程序

返回本节

Page 30: 第6章  汇编语言程序设计

流程图 1 .流程图的概念 流程图是由特定的几何图形 、指向线、

文字说明来表示数据处理的步骤,形象描述逻辑控制结构以及数据流程的示意图。流程图具有简洁、明了、直观的特点。

2.流程图符号表示

( 1 )起止框:表示程序的开始和结束。

•起止框

Page 31: 第6章  汇编语言程序设计

( 2 )判断框

( 3 )处理框

( 4 )调用框

Page 32: 第6章  汇编语言程序设计

( 5 )指向线

( 6 )连接框

返回本节

Page 33: 第6章  汇编语言程序设计

2 顺序程序设计 下面举例说明顺序程序的设计。 【例 4.1】试编写一程序计算以下表达式

的值。 w = ( v- (x * y + z -540 ) ) /

x 式中 x 、y、z、 v 均为有符号字数据。 设x、y、z、v的值存放在字变量X、Y、Z、 V 中,结果存放在双字变量W之中,程序的流程图如图 4.1 所示。返回本章首页

Page 34: 第6章  汇编语言程序设计

图4.1 顺序运算程序流程图

Page 35: 第6章  汇编语言程序设计

源程序如下: 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

Page 36: 第6章  汇编语言程序设计

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

Page 37: 第6章  汇编语言程序设计

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 CODEENDS ;退出 DOS 状态 END START

Page 38: 第6章  汇编语言程序设计

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

中。编写程序如下:

Page 39: 第6章  汇编语言程序设计

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 CODESEGMENT

Page 40: 第6章  汇编语言程序设计

ASSUME DS : DATA , SS : STACK , CS :CODE

BEGIN : MOV AX , DATA MOV DS , AX LEA BX , TAB MOV AL , NO DEL AL XLAT TAB MOV ENGLISH , AL MOV AH , 4CH INT 21H CODE ENDS END BEGIN

Page 41: 第6章  汇编语言程序设计

6.5 分支程序设计 (1) 用条件转移指令实现程序分支 (2) 用跳转表实现多路分支

返回本章首页

Page 42: 第6章  汇编语言程序设计

( 1 ) 用条件转移指令实现程序分支 【例 4.3】编写计算下面函数值的程序: 1 X > 0 Y= 0 X=0 -1 X 设输入数据为 X 、输出数据 Y ,且皆为

字节变量。程序流程图如图 4.2 所示。 程序如下:

Page 43: 第6章  汇编语言程序设计

DATA SEGMENT X DB -10 Y DB ? DATA ENDS STACK SEGMENT STACK DB 200 DUP ( 0 ) STACK ENDS CODESEGMENT ASSUME DS : DATA , SS :

STACK , CS : CODE START : MOV AX , DATA

Page 44: 第6章  汇编语言程序设计

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 JMP EXIT A2 : MOV Y , 1 ; X > 0 , 1→Y EXIT : MOV AH , 4CH INT 21H CODE ENDS END START

Page 45: 第6章  汇编语言程序设计

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 JMP EXIT A2 : MOV Y , 1 ; X > 0 , 1→Y EXIT : MOV AH , 4CH INT 21H CODE ENDS END START

Page 46: 第6章  汇编语言程序设计

•图 4.2 分支运算 程序流程图

Page 47: 第6章  汇编语言程序设计

【例 4.4】 【例 4.4】试编一程序,求三个带符

号字数据中的最大值,并将最大值存入 MAX 字单元中。

设三个带符号数分别在三个字变量 X 、 Y 、 Z 中存储。程序流程图如图 4.3 所示

Page 48: 第6章  汇编语言程序设计

图 4.3   [ 例 4.4] 程序流程图

Page 49: 第6章  汇编语言程序设计

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

Page 50: 第6章  汇编语言程序设计

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

Page 51: 第6章  汇编语言程序设计

L1 : CMP AX , Z ; X > Z ? JLE L2 EXIT : MOV MAX , AX MOV AH , 4CH INT 21H CODEENDS END START

返回本节

Page 52: 第6章  汇编语言程序设计

( 2 ) 用跳转表实现多路分支 【例 4.5 】设某程序有 8 路分支,试根

据给定的 N值( 1~8 ),将程序的执行转移到其中的一路分支。

程序流程如图 4.4 所示。

Page 53: 第6章  汇编语言程序设计
Page 54: 第6章  汇编语言程序设计

程序如下: 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 CODESEGMENT ASSUME DS : DATA , SS :

STACK , CS : CODE

Page 55: 第6章  汇编语言程序设计

START : MOV AX , DATA MOV DS , AX ┆ MOV AL , N DEL AL ADD AL , AL MOV BM , AL MOV BH , 0 JMP TAB[BX]

Page 56: 第6章  汇编语言程序设计

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

Page 57: 第6章  汇编语言程序设计

JMP EXIT ┆ P8 : …… ┆ EXIT : MOV AH , 4CH INT 21H CODEENDS END START 上述程序中的无条件转移指令

的转移地址采用的是变址寻址。同理,转移地址也可以用寄存器间接寻址或基址加变址寻址,读者可自行考虑。

返回本节

Page 58: 第6章  汇编语言程序设计

6.6 循环程序设计

6.1 循环程序的结构 6.2 单重循环程序设计 6.3 多重循环程序设计

返回本章首页

Page 59: 第6章  汇编语言程序设计

6.6 循环程序的结构

1 .初始化部分 2 .循环体部分 3 .循环控制部分

Page 60: 第6章  汇编语言程序设计

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

返回本节

Page 61: 第6章  汇编语言程序设计

一、单重循环程序设计 1 .计数控制

2 .条件控制

Page 62: 第6章  汇编语言程序设计

1 .计数控制 【例 4.7 】已知有 几 个 元素存 放 在 以

BUF 为首址的字节存贮区中,试统计其中正元素的个数。

显然,每个元素为一个 8 位有符号二进制数,统计其中正元素的个数可用循环程序实现。其程序流程图如图 4.6所示。

Page 63: 第6章  汇编语言程序设计

•图4.6

程序流程图

Page 64: 第6章  汇编语言程序设计

【例 4.8】 【例 4.8 】试编写一程序,要求比较两

个字符串 STR1 和 STR 所含字符是否相同,若相同则显示‘ MATCH ’! ,若不相同则显示‘ NO MATCH ’! 。 ( 程序略 )

其流程图如图 4.7所示。

Page 65: 第6章  汇编语言程序设计

•图4.7

程序流程

Page 66: 第6章  汇编语言程序设计

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

其流程图如图 4.8 所示。

2 .条件控制

Page 67: 第6章  汇编语言程序设计
Page 68: 第6章  汇编语言程序设计

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

CODE , SS : STACK

Page 69: 第6章  汇编语言程序设计

START : MOV AX , DATA MOV DS , AX MOV AX , BUF MOV CL , 0 ;计数器为 0 COPA : AND AX , AX 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 返回本节

Page 70: 第6章  汇编语言程序设计

二、多重循环程序设计 【例 4.10】在以 BUF 为首址的字存储区中存放有 N 个有符号数,现需将它们按大到小的顺序排列在 BUF 存储区中,试编写其程序。

我们采用冒泡排序算法从第一个数开始依次对相邻两个数进行比较,如次序对,则不交换两数位置;如次序不对则使这两个数交换位置。可以看出,第一遍需比较( N-1 )次,此时,最小的数已经放到了最后;第二遍比较只需考虑剩下的( N-1 )个数,即只需比较( N-2 )次;第三遍只需比较( N-3 )次,……整个排序过程最多需( N-1 )遍。如下面的 4 个数即是采用冒泡排序比较的例子。

Page 71: 第6章  汇编语言程序设计

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

Page 72: 第6章  汇编语言程序设计
Page 73: 第6章  汇编语言程序设计

程序如下: 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

Page 74: 第6章  汇编语言程序设计

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

Page 75: 第6章  汇编语言程序设计

L : ADD BX , 2 DEC CX JNE LOOP2 MOV CX , DX LOOP

LOOP1 MOV

AH , 4CH INT 21H CODE ENDS END START

Page 76: 第6章  汇编语言程序设计

程序运行后, BUF区中的内容如下:

20 , 9 , 7 , 6 , 3 , 2 ,0 , -4 , -8 , -9 , -10

若要对 N个无符号数按由大到小的顺序排列,只需将指令“ JGE L”改为“ JAE L” 即可。

返回本节

Page 77: 第6章  汇编语言程序设计

6.7 子程序设计

1 子程序的概念 2 子程序的定义 3 子程序设计方法 4 子程序应用举例 5 子程序的嵌套与递归调用

返回本章首页

Page 78: 第6章  汇编语言程序设计

1 子程序的概念 在程序设计中,我们会发现一些多

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

调用子程序的程序称为主调程序或主程序。

返回本节

Page 79: 第6章  汇编语言程序设计

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

返回本节

Page 80: 第6章  汇编语言程序设计

3 子程序设计方法 (1) 信息的保护与恢复 (2) 主程序与子程序参数传递方式

Page 81: 第6章  汇编语言程序设计

(1) 信息的保护与恢复 例如:若子程序 PROG 中改变了寄

存器 AX , BX , CX , DX 的值,则可采用如下方法保护和恢复现场。

PROG PROC PUSH AX PUSH BX PUSH CX ;保

护现场 PUSH DX ┆

Page 82: 第6章  汇编语言程序设计

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

Page 83: 第6章  汇编语言程序设计

(2) 主程序与子程序参数传递方式

( 1 )寄存器法 ( 2 )约定内存单元单元

法 ( 3 )堆栈法

返回本节

Page 84: 第6章  汇编语言程序设计

4 子程序应用举例 【例 4.12】将一个给定的二进制数按位转换

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

Page 85: 第6章  汇编语言程序设计

入口参数: DX 存放待转换的二进制数 CX 存放待转换数的位数( 8 位或 16 位) DI 存放 ASCII 码首地址 出口参数:转换后的字符串存放在以 DI 作指针的字节存贮区中

程序如下: DATA SEGMENT NUM8DB 93H NUM16 DW 0ABCDH ASCBUF DB 20 DUP ( 0 ) DATA ENDS

Page 86: 第6章  汇编语言程序设计

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 MOV [DI+1] , BYTE PTR 0AH

Page 87: 第6章  汇编语言程序设计

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 [DL] , BYTE PTR 0DH MOV [DL+1] , BYTE PTR 0AH MOV [DL+2] , BYTE PTR ‘ ’ $ ; 显示转换后

的字符串 LEA DX , ASCBUF MOV AH , 9 INT 21H

Page 88: 第6章  汇编语言程序设计

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

Page 89: 第6章  汇编语言程序设计

INC DI LOOP

L1 POP AX RET BTASC ENDP CODE ENDS END

START

返回本节

Page 90: 第6章  汇编语言程序设计

5 子程序的嵌套与递归调用 1 .子程序的嵌套 子程序不但可以被主程序调用,而且也可以被其他子程序调用。我们把一个子程序调用另一个子程序称为子程序的嵌套调用。

2 .子程序的递归调用 子程序的递归调用是指一个子程序直接或间

接地调用自己。递归子程序一般对应于数学上对函数的递归定义,它往往能设计出效率较高的程序,完成相当复杂的计算,因而是很有用的。

Page 91: 第6章  汇编语言程序设计

【例 4.15】 【例 4.15】试编制计算 N! ( N≥0 )的程序。

N!=N* ( N-1 ) * ( N-2 ) *……*1 其递归定义如下: 0!=1 N!=N* ( N-1 ) ! ( N > 1 ) 计算 N!的子程序 FACT 的流程图如图 4.10

所示。

Page 92: 第6章  汇编语言程序设计
Page 93: 第6章  汇编语言程序设计

【例 4.16】计算 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

Page 94: 第6章  汇编语言程序设计

START : MOVAX , DATA

MOVDS , AX

MOV AX , N CALL FACT MOV

AX , RESULT MOV

AH , 4CH INT 21H FACT PROC CMP AX , 0 JNE L1

Page 95: 第6章  汇编语言程序设计

MOV RESULT , 1 JMP EXIT L1 : PUSH AX DEC AX CALL FACT POP AX MOV RESULT MOV

RESNLT , AX EXIT : RET FACT ENDP CODE ENDS END START

返回本节

Page 96: 第6章  汇编语言程序设计

6.8 宏指令与条件汇编 宏指令是程序员自己设计的命令,是若干指

令的集合,用以完成某种操作。 1 无参数宏指令的定义与调用 宏指令格式: 名称 MACRO 宏体 ENDM 2 LOCAL 伪指令 如果宏体中有分支、循环,必然有标号,两

次以上调用这样的宏指令必然出现标号重复定义的错误,可以用 LOCAL 解决这类错误。

Page 97: 第6章  汇编语言程序设计

3 有参数宏定义与调用 格式: 4 宏指令与子程序的区别 6.8.2 条件汇编 格式 1 : IF 条件 指令集合 1 ELSE 指令集合 2 ENDIF 格式 2 : IF 条件 指令集合 ENDIF

Page 98: 第6章  汇编语言程序设计

6.9 代码转换 代码转换是凶横许设计的常见课题,由于键盘输入、屏幕显示、打印机输出都使用字符 ASCII 码,而指令的运算对象及其结果都是一串 0 、 1 代码。输出显示的格式可能是二进制数、十进制数或十六进制数,因此许多场合都要进行代码转换。例 6.9.1 键盘输入的一位十进制数 ASCII 码转换为二进制数显示。( P113 )例 6.9.2 二进制 数 转换为十六进制 数 显 示 。( P116 )例 6.9.3 二进制 数 转换为十进制 数 显 示 。( P116 )例 6.9.4 BCD 码转换为二进制数显示。( P120 )

Page 99: 第6章  汇编语言程序设计

6.10 数值计算在汇编语言中,可进行数值计算的仅有加、减、乘、除、移位等作为基本的指令。运用这些基本指令哪怕是完成稍微复杂一些的数值计算都是比较困难的。首先要探讨计算方法,要把某一些问题分解成能够用加、减、乘、除完成的基本操作,然后才能着手编程。例 6.10.1 求正整 数 N 的 开平方近似值 。( P121 )例 6.10.2 多字节 BCD 码数相加。计算两个组合的四字节 BCD 码数之和。( P122 )

Page 100: 第6章  汇编语言程序设计

6.11 数据处理数据处理涉及地面比较广,其中字符处理和表格处理都属于数据处理范畴。

6.12 字符串地动态显示技术例 6.12.1

Page 101: 第6章  汇编语言程序设计

6.13 模块化程序设计1 . PUBLIC 伪指令格式: PUBLIC 符号 [,符号 ]功能:说明其后的符号是全局符号。全局符号能被其他模块引用。2 . EXTRN 伪指令格式: EXTRN 符号:类型 [,符号:类型 ]功能:说明在本模块中需要引用的、由其他模块定义的符号,即外部符号。

返回本章首页

Page 102: 第6章  汇编语言程序设计

3 . INCLUDE 伪指令格式: INCLUDE 盘符: \ 路径 \ 文件名 .扩展名功能:通知汇编程序把指定的文件“拷贝”一份,插入到该语句的下方供汇编时使用6.13.2 模块化程序设计考虑( 1 )在模块化程序设计之前要有一个总体规划,合理地划分模块,使每一个模块有相对独立地功能,尽量减少模块之间的调用。( 2 )在实模式下,链接之后的同类型逻辑段的体积不能超过 64K 。( 3 )模块之间,同类型逻辑段的组合与否,是需要重点考虑的问题。

Page 103: 第6章  汇编语言程序设计

( 4 )模块之间的转移和调用( 5 )模块之间出现符号名引用的时候必须用PUBLIC , EXTRN 语句说明。6.13.4 宏指令共享

Page 104: 第6章  汇编语言程序设计

【例 4.17 】 【例 4.17 】用模块化程序设计方法编制一个把十

进制数 N ( 16bit )转换成十六进制数的程序,要求待转换数 N 由键盘输入,转换结果在屏幕上显示出来。首先建立两个模块 A : READ.ASM和模块 B : SCREEN.ASM 。其中模块 A :完成转换功能,模块 B 完成显示功能。

模块 A : READ.ASM PUBLIC crlf,m EXTRN disp:near

data SEGMENT PUBLIC 'data'

n DB 0ah,0dh,'input=$' m DB 'output=$' crlf DB 0ah,0 data ENDS

Page 105: 第6章  汇编语言程序设计

code SEGMENT PUBLIC'code'

ASSUME cs:code,ds:data start PROC far PUSH ds MOV ax,0 PUSH ax MOV ax,data MOV ds,ax REPEat: MOV bx,0 MOV ah,9 LEA dx,n INT 21h CALL DECibin CALL disp MOV ah,1 INT 21h CMP al,0dh JZ END1 JMP REPEat END1: RET start ENDP

Page 106: 第6章  汇编语言程序设计

DECibin PROC near newchar: MOV ah,1 INT 21h SUB al,30h JL exit CMP al,39h JG exit CBW XCHG ax,bx MOV cx,10 MUL cx XCHG ax,bx ADD bx,ax JMP

newchar exit: RET DECibin ENDP code ENDS END start

Page 107: 第6章  汇编语言程序设计

模块 B:

PUBLIC disp EXTRN crlf:byte,m:byte

code SEGMENT PUBLIC 'code'

ASSUME cs:code disp PROC near MOV ah,09h LEA dx,m INT 21h MOV ch,4

Page 108: 第6章  汇编语言程序设计

rotate: MOV cl,4 ROL bx,cl MOV al,bl AND al,0fh ADD al,30h CMP al,3ah JL printit ADD al,07h printit: MOV dl,al MOV ah,2 INT 21h DEC ch JNZ rotate RET disp ENDP code ENDS END