• 沒有找到結果。

汇编语言程序设计基本方法

5.3.1 程序设计的基本步骤

(1)分析问题。

对题目给出的已知条件和要完成的任务进行详细的了解和分析,将实际问题转化为计算 机可以处理的问题。

(2)确定算法。

算法,即利用计算机解决问题的方法和步骤。计算机一般只能进行最基本的算术运算和 逻辑运算,要完成较为复杂的运算和控制操作,就必须选择合适的算法。

(3)设计流程。

将算法以流程图的方式画出来。

画流程图是指用各种图形、符号、指向线等来说明程序设计的过程。国际通用的图形和 符号说明如下:

1)椭圆框:起止框,在程序的开始和结束时使用,如图 5-3(a)所示。

2)矩形框:处理框,表示要进行的各种操作,如图 5-3(b)所示。

3)菱形框:判断框,表示条件判断,以决定程序的流向,如图 5-3(c)所示。

4)指向线:流程线,表示程序执行的流向,如图 5-3(d)所示。

(a)起止框 (b)处理框 (c)判断框 (d)流程线

图5-3 国际通用的流程图图形

(4)分配空间。

合理分配存储空间,即分段和数据定义,合理地使用寄存器。

(5)编写程序。

根据前面确定的算法流程图,采用汇编程序设计语言编写程序。

(6)调试运行。

程序编写好以后,检查语法错误,上机汇编、连接、调试运行,检验程序是否正确,能 否实现预期功能。

5.3.2 顺序、分支与循环程序设计

利用计算机解决实际问题时,其操作控制执行步骤有时是按顺序执行的,有时需要根据 实际情况选择某一个分支的操作执行,有时需要对某一些操作步骤反复执行,与之相对应,就 有3 种程序结构:顺序结构、分支结构、循环结构。

1.顺序结构

顺序结构程序完全按指令书写的前后顺序,从头至尾逐条执行,是最常用、最基本的程 序结构。常用于处理查表程序、计算表达式程序。

例 5-26 编写程序计算表达式: a * b c f d e

= +

− 。 DATA SEGMENT

A DB 5 B DB 10 C DB 15 D DB 30 E DB 20 F DB ? DATA ENDS

CODE SEGMENT

ASSUME CS: CODE, DS: DATA

START: MOV AX,DATA ;初始化 DS

MOV DS,AX

MOV AX,0

MOV AL,A

MUL B ;AX=A*B MOV BL,C

MOV BH,0

ADD AX,BX ;AX=A*B+C MOV CL, D

SUB CL, E ;CL=D-E

DIV CL ;AL=AX/CL=(A*B+C)/(D-E)

ASSUME DS:DATA,CS:CODE START: MOV AX,DATA

ASSUME DS:DATA,CS:CODE START: MOV AX,DATA

MOV DS,AX ;初始化

MOV AH,4CH

INT 21H ;返回 DOS

CODE ENDS

END START

(a)单分支结构 (b)双分支结构 图5-4 单、双分支结构流程图

(3)多分支程序。需要对多个条件进行判断,每个条件都对应一个分支,满足某个条件 时就进入相对应的分支执行。流程图如图5-5 所示。

图5-5 多分支结构流程图 对于多分支程序结构,可以采用以下两种解决方法:

1)逻辑分解方法。将多分支结构以逻辑等效的方法分解为一串双分支结构。

例 5-29 求符号函数Y 的值:

DATA SEGMENT X DB -10 Y DB ? DATA ENDS CODE SEGMENT

ASSUME DS:DATA,CS:CODE Y=

1 (X>0)

-1 (X<0)

0 (X=0)

满足条件1 满足条件2 满足条件N

分支语句体1 分支语句体2 …… 分支语句体N 条件判断

Y N

分支语句体1

分支语句体2 JMP N

语句体

分支语句体 JXX 条件满足吗? Y

JXX 条件满足吗?

START: MOV AX,DATA

FUN DW FUN0,FUN1,FUN2,FUN3,FUN4

;将标号 FUN0、FUN1、FUN2、FUN3、FUN4 偏移地址存入变量 FUN 中 DATA ENDS

CODE SEGMENT

ASSUME DS:DATA,CS:CODE START: MOV AX,DATA

INT 21H CODE ENDS END START

(4)说明:

①对于既能用双分支结构,又能用单分支结构实现的程序,宜采用单分支结构,以减少 转移次数,程序结构简单。

②对于多分支结构程序,宜采用地址表法,以减少转移次数,程序结构简单。

③对分支结构程序进行测试时,应对每一个分支都进行检测,才能保证整个程序的正 确性。

3.循环结构

根据某一条件是否成立判断是否需要重复执行某个语句组,这种程序结构称为循环结构。

(1)说明:

①一个循环结构一般由循环条件控制、循环体两部分组成。

循环条件控制:对循环条件进行判断,决定是否继续循环。

循环体:重复执行的语句组。

注意:循环体中应对循环条件的值进行修改,否则将会成为死循环(循环无限次)。

②根据循环条件控制所在的位置,可将循环结构分为两种:

z “先判断、后循环”:先判断循环条件,再决定是否执行循环体。

z “先循环、后判断”:先执行循环体(至少一次),再判断循环条件。

③用的循环指令有:

z 循环指令:LOOP、LOOPE/LOOPZ、LOOPNE/LOOPNZ。

z 转移指令:JCXZ、JXX。

其中 LOOP、JCXZ 常用于循环次数固定的循环结构,称这种循环结构为计数循环;

LOOPE/LOOPZ、LOOPNE/LOOPNZ、JXX 常用于循环次数不定的循环结构,称这种循环结构 为条件控制循环。

(2)应用举例。

1)计数循环:循环次数已知,用计数器 CX 计数来控制循环次数,要求在循环之前设置 CX 的值,即将循环次数送入CX 中,然后每循环一次计数器值减 1,直至其值减为 0 则不再循环。

例 5-31 设计一个程序,求1+2+" +99+100 的和,结果保存在变量 RESULT 中。

DATA SEGMENT RESULT DW 0 DATA ENDS CODE SEGMENT

ASSUME CS:CODE,DS:DATA START: MOV AX,DATA

MOV DS,AX

MOV AX,1

MOV CX,100 L0: ADD RESULT,AX

INC AX LOOP L0

MOV AH,4CH

INT 21H CODE ENDS

END START 的值大于MAX(或小于 MIN),则将它送入 MAX(或 MIN)中,这样循环结束后,MAX(或 MIN)里面存放的就是数组的最大值(或最小值)。

例 5-33 数组ARRAY 的长度为 N(即数组 ARRAY 中共有 N 个数,假设均为无符号字 节数),请将数组中的数按升序(从小到大)排序。

分析:排序算法有很多种,这里采用冒泡排序算法,其算法思想为:

①第 1 趟:从数组的最左边开始,依次将相邻两个数作比较,若前者大于后者,则交换 两者的值,经N-1 次两两相邻比较后,最大的数已交换到最后一个位置。

②第2 趟:对前 N-1 个数,按上法两两相邻比较,经 N-2 次比较后得到次大的数,安置 在第N-1 个元素的位置。

③重复上述过程,经过N-1 趟冒泡排序后,数据呈升序排列。

DATA SEGMENT

ARRAY DB 10,58,23,94,85,32,70,5,42,62 N EQU $-ARRAY ;N 为数组长度 DATA ENDS

CODE SEGMENT

ASSUME CS:CODE,DS:DATA START: MOV AX,DATA

MOV DS,AX

MOV CX,N-1 ;设置外层循环次数为 N-1,即冒泡排序趟数 L0: PUSH CX ;保存外层循环次数计数器

LEA SI,ARRAY

L1: MOV AL,[SI]

MOV AH,[SI+1]

CMP AL,AH ;相邻两个数作比较

JLE L2 ;若前者小于等于后者,则不交换,转去比较下一对相邻

;的两个数

MOV [SI+1],AL ;否则(即前者大于后者),交换两者的值

MOV [SI],AH

L2: INC SI

LOOP L1 ;内存循环两两比较,循环次数刚好等于外层循环次数计数器

;的值,所以不需要另外设置内层循环计数器 CX 的值

POP CX ;恢复外层循环次数计数器

LOOP L0 ;继续外层循环

MOV AH,4CH ;返回 DOS

INT 21H

CODE ENDS

END START

5.3.3 子程序设计

通常将一个大的程序按照功能划分为几个子程序(子程序就是一个功能上相对独立的程 序段,可以被多次重复调用。在一个完整的程序中,可以有多个子程序,子程序能被别的程序 所调用,也可以调用其他子程序,也称过程),通过调用各个子程序来实现程序的功能。

在定义子程序时,一般需要包含以下几个部分:

z 保护现场 z 子程序体 z 恢复现场 z 子程序返回

调用子程序时,子程序与主程序之间往往存在着数据的交流,称主程序传递给子程序的

数据为入口参数,称子程序返回给主程序的结果数据为出口参数。

常采用的参数传递方法有:通过寄存器传递、通过共享变量传递、通过堆栈传递。

(1)通过寄存器传递参数。

把入口参数、出口参数存放于约定的寄存器中,这是最常用的参数传递方式。通过寄存 器传递参数时,需要视具体情况来选择是否需要对入口参数、出口参数进行保护和恢复。由于 通用寄存器个数有限,通过寄存器传递参数的方法只适合参数个数较少的场合。

例 5-34 编写一个子程序,在数据块中查找某个指定数据,若找到则把该数据在数据块 中的序号返回,若找不到则返回-1。

DATA SEGMENT

ARRAY DB 10,58,23,94,85,32,70,5,42,62

N EQU $-ARRAY ;N 为数组长度 DATA ENDS

CODE SEGMENT

ASSUME CS:CODE,DS:DATA START: MOV AX,DATA

MOV DS,AX

LEA SI,ARRAY

MOV CX,N

MOV DL,94

CALL LOOKUP ;调用子程序

MOV AH,4CH ;返回 DOS

INT 21H

;子程序名:LOOKUP

;功能:片内 RAM 中的数据检索

;入口参数:SI 存放数据块首地址,CX 存放数据块长度,DL 存放要查找的数据

;出口参数:若找到,则将数据的序号存入 DI,否则存-1 到 DI LOOKUP PROC

PUSH CX

PUSH SI

MOV DI ,-1

L0: CMP DL,[SI]

JZ L1

INC SI

LOOP L0

JMP L2

L1: MOV DI,SI

SUB DI,OFFSET ARRAY L2: POP SI

POP CX

RET LOOKUP ENDP CODE ENDS END START

(2)通过共享变量传递参数。把入口参数、出口参数存放于约定的内存共享变量中。若 子程序和调用程序在同一程序模块中,则子程序可直接访问模块中的变量,进行参数传递;若 子程序和调用程序在两个不同的程序模块中,需要利用PUBLIC、EXTREN 对共享变量进行声 明才能访问共享变量。

若调用程序还要引用共享变量原来的值,则需要对共享变量进行保护和恢复。

BUF DW 10,58,23,94,85,32,70,5,32,62

N EQU ($-BUF)/2 ;N 为数据块长度 DATA ENDS

CODE SEGMENT

ASSUME CS:CODE,DS:DATA START: MOV AX,DATA

MOV DS,AX

MOV AX,OFFSET BUF

PUSH AX

CALL AVERAGE ;调用子程序

MOV AH,4CH ;返回 DOS

INT 21H

;子程序名:AVERAGE

;功能:求数据块中若干数据的平均值

;入口参数:数据块的首地址,压入堆栈

;出口参数:平均值,压入堆栈 AVERAGE PROC

POP BX

POP SI

MOV AX,0

MOV CX,N

L0: ADD AX,[SI]

ADD SI,2

LOOP L0

MOV CL,N

DIV CL

CBW

PUSH AX

PUSH BX

RET AVERAGE ENDP CODE ENDS END START

5.3.4 子程序的嵌套与递归 1.子程序的嵌套

在一个子程序中调用其他的子程序,称为子程序的嵌套,如图5-6 所示。嵌套的层数不限,

只要堆栈空间足够即可。

主程序 子程序SUB1 子程序SUB2 SUB1 PROC SUB2 PROC

……

CALL SUB1

…… ……

CALL SUB2

…… …… ……

……

RET RET 图5-6 子程序嵌套

例 5-37 ALDISP PROC PUSH AX

PUSH CX ;实现 AL 内容的显示 PUSH AX ;暂存 AX

MOV CL,4

SHR AL,CL ;转换 AL 的高 4 位 CALL HTOASC ;子程序调用(嵌套)

POP AX ;转换 AL 的低 4 位 CALL HTOASC ;子程序调用(嵌套)

POP CX

POP AX

RET ALDISP ENDP

;将 AL 低 4 位表达的一位十六进制数转换为 ASCII 码 HTOASC PROC

PUSH AX PUSH BX PUSH DX

MOV BX,OFFSET ASCII ;BX 指向 ASCII 码表 AND AL,0FH ;取得一位十六进制数

XLAT ASCII ;换码:AL←CS:[BX+AL],注意数据在代码段 CS MOV DL,AL ;显示

MOV AH,2 INT 21H

POP DX

POP BX

POP AX

RET ;子程序返回

;子程序的数据区

ASCII DB 30H,31H,32H,33H,34H,35H,36H,37H DB 38H,39H,41H,42H,43H,44H,45H,46H HTOASC ENDP

注意:子程序可以与主程序共用一个数据段,也可以使用不同的数据段(注意修改DS),

还可以在子程序最后设置数据区(利用CS 寻址)。

2.子程序的递归

2.子程序的递归

相關文件