05汇编语言程序设计1_第1页
05汇编语言程序设计1_第2页
05汇编语言程序设计1_第3页
05汇编语言程序设计1_第4页
05汇编语言程序设计1_第5页
已阅读5页,还剩116页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、第第5章章 汇编语言程序设计汇编语言程序设计 本章主要内容本章主要内容 本章介绍汇编语言程序设计的基本方法,包本章介绍汇编语言程序设计的基本方法,包 括:顺序程序设计、分支程序设计、循环程括:顺序程序设计、分支程序设计、循环程 序设计和子程序的设计。序设计和子程序的设计。 5.1 汇编语言源程序设计的步骤汇编语言源程序设计的步骤 5.1.1 分析问题分析问题 首先必须明确求解问题的意义和任务。对给出的已首先必须明确求解问题的意义和任务。对给出的已 知条件和要完成的任务进行详细地了解和分析,将知条件和要完成的任务进行详细地了解和分析,将 一个实际的问题转化为计算机可以处理的问题。一个实际的问题转

2、化为计算机可以处理的问题。 5.1.2 确定确定算法算法 其次就是确定解决问题的算法。所谓算法,简单地其次就是确定解决问题的算法。所谓算法,简单地 说就是说就是计算机能够实现的有限的解题计算机能够实现的有限的解题步骤步骤。我们知。我们知 道,计算机只能进行最基本的算术运算和逻辑运算,道,计算机只能进行最基本的算术运算和逻辑运算, 要完成较为复杂的运算和控制操作,必须选择合适要完成较为复杂的运算和控制操作,必须选择合适 的算法,这是正确编程的基础。的算法,这是正确编程的基础。 5.1.3 绘制绘制流程图流程图 将提出的算法或编程思想用流程图的方式画将提出的算法或编程思想用流程图的方式画 出来。图

3、出来。图5-1给出了流程图中较为通用的几种给出了流程图中较为通用的几种 符号。符号。 起始框和终止框起始框和终止框 执行框执行框 判断框判断框 联系框联系框 5.1.4 程序设计程序设计 根据流程图进行程序设计就是采用某种程序根据流程图进行程序设计就是采用某种程序 设计语言来实现上面已确定的算法,此过程设计语言来实现上面已确定的算法,此过程 有些书上称为有些书上称为编码编码。 本书所介绍的是采用汇编语言编写程序。本书所介绍的是采用汇编语言编写程序。 采用汇编语言编写程序应注意以下几个问题:采用汇编语言编写程序应注意以下几个问题: 必须详细了解必须详细了解CPU的编程模型、指令系统、的编程模型、

4、指令系统、 寻址方式及相关伪指令;寻址方式及相关伪指令; 必须进行存储空间和工作单元的合理分配;必须进行存储空间和工作单元的合理分配; 多次使用的程序段落可采用子程序或宏指令;多次使用的程序段落可采用子程序或宏指令; 尽可能用尽可能用标号或变量标号或变量来代替绝对地址和常数;来代替绝对地址和常数; 5.1.5 程序程序检验检验 程序编写好以后,必须经过书面检查和上机程序编写好以后,必须经过书面检查和上机 调试,以便说明程序是否正确。检验时,应调试,以便说明程序是否正确。检验时,应 预先选择典型数据,检查是否可以得到预期预先选择典型数据,检查是否可以得到预期 结果。结果。 5.1.6 编写编写说

5、明说明文件文件 一个完整的软件应有相应的说明文件,这不一个完整的软件应有相应的说明文件,这不 仅便于用户使用,也便于对程序的维护和扩仅便于用户使用,也便于对程序的维护和扩 充。说明文件主要应包括程序的功能和使用充。说明文件主要应包括程序的功能和使用 方法,程序的基本结构和所采用的主要算法方法,程序的基本结构和所采用的主要算法 以及程序必要说明和注意事项等。以及程序必要说明和注意事项等。 32位微机系统中,位微机系统中,CPU可以工作在实模式、可以工作在实模式、 保护模式和虚拟模式下,本章仅介绍基于保护模式和虚拟模式下,本章仅介绍基于实实 模式模式的程序设计。的程序设计。 5.2 顺序程序设计顺

6、序程序设计 顺序结构也称线性结构,其特点是其中的语顺序结构也称线性结构,其特点是其中的语 句或结构被连续执行,顺序程序是句或结构被连续执行,顺序程序是最简单最简单的,的, 也是也是最基本最基本的一种程序结构形式。的一种程序结构形式。 CPU总是根据总是根据CS:IP获取下一条指令所在存储获取下一条指令所在存储 单元的地址,并自动对单元的地址,并自动对IP不断执行加不断执行加1操作。操作。 这种结构的程序从开始到结尾一直是顺序执这种结构的程序从开始到结尾一直是顺序执 行的,中途没有任何分支和循环。行的,中途没有任何分支和循环。 从流程图来看,顺序结从流程图来看,顺序结 构除了一个起始框,一构除了

7、一个起始框,一 个结束框外,就是若干个结束框外,就是若干 个执行框,没有判断框。个执行框,没有判断框。 具有顺序结构的程序叫具有顺序结构的程序叫 做简单程序。做简单程序。 顺序结构顺序结构 开始开始 结束结束 例:实现例:实现625*210M。 M DD ? MOV AX,625 MOV BX,210 MUL BX ;16位乘法:结果为位乘法:结果为32位位 MOV M ,AX MOV M+2,DX 注:算术运算指令需要注意注:算术运算指令需要注意字长字长、区分、区分无符无符 号号/有符号有符号、溢出溢出等问题。等问题。 例例5.9:P161。 5.3 分支程序设计分支程序设计 分支程序有分支

8、程序有3种结构,即种结构,即简单分支简单分支、复合分支、复合分支 和多分支。和多分支。 复合分支复合分支是指通过一个简单分支不能实现判是指通过一个简单分支不能实现判 断,必须多个分支合起来才能进行判断的情断,必须多个分支合起来才能进行判断的情 况。况。 在设计多分支转移程序时,如果分支太多,在设计多分支转移程序时,如果分支太多, 则平均转移速度太慢。可以采用转移地址表则平均转移速度太慢。可以采用转移地址表 来实现多分支转移,可以提高平均转移速度。来实现多分支转移,可以提高平均转移速度。 多分支多分支结构相当于一个多路开关,在程序设结构相当于一个多路开关,在程序设 计中通常是根据某计中通常是根据

9、某寄存器寄存器或某或某存储单元存储单元的内的内 容容(一个数字一个数字)进行程序转移。进行程序转移。 分支程序的结构示意图分支程序的结构示意图 (a) 简单分支简单分支 (b) 复合分支复合分支 条件成立?条件成立? Y Y 条件成立?条件成立? N 语句语句 语句语句 1语句语句 2 语句语句 1语句语句 2语句语句 n 情况情况1情况情况2情况情况n 表达式计算结果是表达式计算结果是 (c) 多路分支多路分支 1.简单分支简单分支 通常,是在执行了通常,是在执行了算术比较指令算术比较指令CMP,或者或者 逻辑比较指令逻辑比较指令TEST之后,根据之后,根据Z,S,O,P, C等各种等各种状

10、态标志状态标志进行条件转移。进行条件转移。 如果条件成立:跳转到指定指令开始执行;如果条件成立:跳转到指定指令开始执行; 否则,顺序执行转移指令的下一条指令。否则,顺序执行转移指令的下一条指令。 例例:将一个将一个16位二进制数以二进制数的方式显示。位二进制数以二进制数的方式显示。 CODE SEGMENT USE16 ASSUME CS:CODE BEG: MOV BX,5678H ;BX中为将要处理的中为将要处理的16位二进制数位二进制数 MOV CX,16 ;每次移出每次移出1位、循环位、循环16次次 LAST:MOV DL,0 RCL BX,1 ;BX循环左移一位循环左移一位 JNC

11、NEXT ;若进位标志为若进位标志为0则转,显示则转,显示0 MOV DL,1 ;为为1时,则显示时,则显示1 NEXT: MOV AH,2 INT 21H LOOP LAST MOV AH,4CH INT 21H CODE ENDS END BEG 思考:思考: 例中的例中的RCL换为换为SHL、SAL、ROL,是否可,是否可 行?行? “左移左移”换为换为“右移右移” 是否可行?是否可行? 2.复杂分支复杂分支 在简单分支的某个分支上进行其他条件的判在简单分支的某个分支上进行其他条件的判 断。断。 【例例】 设有一个带符号的设有一个带符号的16位数存于位数存于ALFA 单元中。编程判断该数

12、,若单元中。编程判断该数,若大于大于0、将、将BETA 单元置为单元置为0FFH;若;若等于等于0、将、将BETA+1单元置单元置 为为0FFH;若;若小于小于0、将、将BETA+2单元置为单元置为 0FFH。 解解:程序设计如下程序设计如下: START:MOV AX,DATA ;设置段地址设置段地址 MOV DS,AX MOV AX,ALFA ;取操作数取操作数 OR AX,AX ;设置状态标志位设置状态标志位 ;是否可以改为是否可以改为AND?XOR呢?呢? JS LOOP1 ;SF=1,小于小于0转移转移 JZ LOOP2 ;ZF=0,等于等于0转移转移 MOV BETA,0FFH ;

13、大于大于0 JMP LOOP3 ;能否省略?能否省略? LOOP1:MOV BETA+2, 0FFH JMP LOOP3 ;能否省略?能否省略? LOOP2:MOV BETA+1,0FFH LOOP3: END START 思考:本例可以采用思考:本例可以采用CMP AX,0的做法:的做法: 但是,必须使用但是,必须使用JG/JL,而不能使用,而不能使用JA/JB。 例:实现下列符号函数例:实现下列符号函数Y的功能,其中:的功能,其中: -128X+127。 1 当当X0时时 Y 0 当当X0时时 -1 当当X0时时 X DB?;自变量自变量X Y DB ?;函数值函数值Y MOV AL,0

14、;同时假设同时假设Y=0 CMP X,AL JG BIG ;X大于大于0 JZ SAV ;X等于等于0 、Y=0 MOV AL,0FFH ;X小于小于0、Y= -1 JMP SHORT SAV BIG: MOV AL,1 ;Y=1 SAV: MOVY,AL ;保存结果保存结果 例例5.11P162复合判断。判断一个复合判断。判断一个无符号数无符号数 X与已知两个无符号数与已知两个无符号数N1、N2(N1N2)之间之间 的大小关系,并显示判断结果。的大小关系,并显示判断结果。 DATA SEGMENT USE16 MESG1 DB N1=X=N2$ MESG2 DB XN2$ NUMBER DB

15、 ? N1 EQU 22 N2 EQU 88 DATA ENDS CODE SEGMENT USE16 ASSUME CS:CODE,DS:DATA BEG:MOV AX,DATA MOV DS,AX MOV DX,OFFSET MESG1;预设一种结果预设一种结果 CMP NUMBER,N1 ;无需无需PTR JNC NEXT MOV DX,OFFSET MESG2 JMP DISP NEXT:CMP NUMBER,N2+1 JC DISP ;如果上一条指令如果上一条指令N2+1改用改用N2则则JC应改为应改为JBE MOV DX,OFFSET MESG3 DISP:MOV AH,9 INT

16、 21H MOV AH,4CH INT 21H CODE ENDS END BEG 思考:如果思考:如果NUM的值分别为以下情况、结果如何:的值分别为以下情况、结果如何: 55 ? A a -1 3.多分支多分支 在一个程序中,如果分支太多,将会出现连在一个程序中,如果分支太多,将会出现连 续多次条件判断,则平均转移速度较慢,即续多次条件判断,则平均转移速度较慢,即 程序执行程序执行效率较低效率较低。 多路分支相对于一个多路多路分支相对于一个多路开关开关,通常是根据,通常是根据 一个一个存储单元存储单元或者一个或者一个寄存器寄存器的内容的内容( )进行程序:进行程序:。 例例5.12P163:

17、设计一个支持:设计一个支持256个分支的段个分支的段 内转移程序。内转移程序。 设设JUMP中有一个数中有一个数X。 若若X=0,转移到标号为,转移到标号为P000的程序段。的程序段。 若若X=1,转移到标号为,转移到标号为P001的程序段。的程序段。 若若X=255,转移到标号为,转移到标号为P255的程序段。的程序段。 图示;假设图示;假设JUMP为为3。 .486 DATA SEGMENT USE16 JUMP DB ? TAB DW P000 ;P000是标号是标号 DW P001 . . DW P255 DATA ENDS CODE SEGMENT USE16 ASSUME CS:C

18、ODE,DS:DATA BEG:MOV AX,DATA MOV DS,AX MOV BL,JUMP MOV BH,0 ;2句可否合并进入句可否合并进入BX? ;能否直接使用;能否直接使用BX? ADD BX,BX ;乘以乘以2操作、为什么?操作、为什么? MOV SI,OFFSET TAB JMP BX+SI P000:. . P001:. . . . P255:. . CODE ENDS END BEG 例例统计一个班学生的考试分数在各个分数段统计一个班学生的考试分数在各个分数段 的情况。分数在的情况。分数在059的个数在的个数在Sort存储单元,存储单元, 6069的在的在Sort+1单元

19、,单元,9099的在的在Sort+4 单元。程序如下:单元。程序如下: DATA SEGMENT SORT DB 5 DUP(0) ADDR DW S59,S69,S79,S89,S99 TABLE DB 59,60,68,77,71,78,90,95、 DB * ;循环结束标志循环结束标志 DATA ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA START:MOV AX,DATA MOV DS,AX MOV DI,OFFSET TABLE ;逐个读取分数逐个读取分数 MOV SI,OFFSET ADDR NEXT:MOV AL,DI ;逐个读取分数逐个读取

20、分数 CMP AL,* JE OVER INC DI ;准备读取下一个数据准备读取下一个数据 CMP AL,60 JAE NEXT MOV AL,0 ;当分数低于当分数低于60时,时,AL直接置直接置0 NEXT :MOV AH,0 ;AL/10 5 MOV BL,10 DIV BL SUB AL,5 ;AL介于介于14 MOV BL,AL MOV BH,0 ;BX介于介于04 ADD BX,BX ;乘以乘以2 JMP SI+BX S59:INC SORT JMP NEXT S69:INC SORT+1 JMP NEXT S79:INC SORT+2 JMP NEXT S89:INC SORT

21、+3 JMP NEXT S99:INC SORT+4 JMP NEXT OVER:MOV CX,5 ;显示结果;显示结果 MOV SI,OFFSET SORT-1 DISP:MOV AH,2 MOV DL,13 INT 21H MOV AH,2 MOV DL,10 INT 21H INC SI MOV DL,SI ADD DL,30H MOV AH,2 INT 21H LOOP DISP MOV AH,4CH INT 21H CODE ENDS END START 5.4 循环程序设计循环程序设计 循环程序一般应包括以下几部分:循环程序一般应包括以下几部分: (1)循环初始化循环初始化。通常是

22、指设置循环的初始条件,包。通常是指设置循环的初始条件,包 括设置循环计数器的初值等,常使用寄存器或者内括设置循环计数器的初值等,常使用寄存器或者内 存单元作为循环计数器。存单元作为循环计数器。 (2)循环体循环体。 (3) 循环控制循环控制部分。根据循环的条件是否满足来决定部分。根据循环的条件是否满足来决定 程序是否循环,通常用一个简单分支来实现循环控程序是否循环,通常用一个简单分支来实现循环控 制。制。 特别要注意循环入口和循环次数的正确设置、地址特别要注意循环入口和循环次数的正确设置、地址 指针及循环控制条件的修改等,否则会得不到期望指针及循环控制条件的修改等,否则会得不到期望 的结果。的

23、结果。 循环结构可以分为单循环、双循环和多重循环。三循环结构可以分为单循环、双循环和多重循环。三 重及以上的循环就比较复杂了。重及以上的循环就比较复杂了。 例例求求最大数最大数。假设从内存的。假设从内存的BUF单元开始存单元开始存 有一个以有一个以ASCII码码方式表示的字符串,求其中方式表示的字符串,求其中 的最大数的最大数(即即ASCII码最大的字符的码最大的字符的ASCII值值), 显示到屏幕上。显示到屏幕上。 注意:注意:ASCII码参与比较时视为码参与比较时视为无符号数无符号数! 必须使用必须使用JA/JB,而不能使用,而不能使用JG/JL 解法解法1循环次数已知循环次数已知 DAT

24、A SEGMENT USE16 BUF DB QWERTYUIOP123 COUNT EQU $-BUF ;统计字节个数、即统计字节个数、即循环次数循环次数 MAX DB MAX=,?,0DH, 0AH, $ DATA ENDS CODE SEGMENT USE16 ASSUME CS:CODE,DS:DATA BEG:MOV AX,DATA MOV DS,AX MOV AL,0 ;最大数最大数0送送AL LEA BX,BUF MOV CX,COUNT LAST: CMP BX,AL JB NEXT MOV AL,BX ;大数大数 NEXT:INC BX LOOP LAST MOV MAX+4

25、,AL MOV AH,9 LEA DX,MAX INT 21H MOV AH,4CH INT 21H CODE ENDS END BEG 在上面的例子里面,循环次数已知,在已知在上面的例子里面,循环次数已知,在已知N 个数中,求最大数时:个数中,求最大数时: (1)需要比较)需要比较N次次: 给定一个假设的最小无符号数给定一个假设的最小无符号数0; (2)只需要)只需要N-1次:次: 假设第一个数即是最大数。假设第一个数即是最大数。 解法解法2 循环结束标志循环结束标志 当循环次数不确定时,采用当循环次数不确定时,采用循环结束标志循环结束标志控控 制循环。制循环。 此例中:定义一个值为此例中:

26、定义一个值为-1的的FLAG单元作为字单元作为字 符串的结束标志。符串的结束标志。 解法解法2 求字符串中最大字符,利用求字符串中最大字符,利用结束标志结束标志。 DATA SEGMENT USE16 BUF DB QWERTYUIOP123 FLAG DB -1 MAX DB MAX=,?,0DH, 0AH, $ DATA ENDS CODE SEGMENT USE16 ASSUME CS:CODE,DS:DATA BEG: MOV AX,DATA MOV DS,AX MOV AL,0 ;最小无符号数最小无符号数0送送AL LEA BX,BUF LAST:CMP BYTE PTR BX,-1

27、 JE DISP CMP BX,AL JC NEXT MOV AL,BX NEXT:INC BX JMP LAST DISP:MOV MAX+4,AL MOV AH,9 MOV DX,OFFSET MAX INT 21H MOV AH,4CH INT 21H CODE ENDS END BEG 例例设某数据块存放在设某数据块存放在BUFFER开始的开始的100个字节单元中。试个字节单元中。试 编程统计数据块中编程统计数据块中负数的个数负数的个数,并将统计的结果存放到,并将统计的结果存放到 NUMBER单元中。单元中。 解解:程序如下程序如下: START:MOV AX,DATA MOV DS,

28、 AX LEA SI,BUFFER ;设置数据块指针设置数据块指针 MOV CX,100 ;设置循环次数设置循环次数 MOV BL,0 ;统计个数统计个数 LOOP1:MOV AL,SI ;取数据取数据 OR AL,AL ;设置设置状态标志位状态标志位 JNS LOOP2 ;非负转移非负转移 INC BL ;计数器加计数器加1 LOOP2:INC SI ;修改指针修改指针 LOOP LOOP1 ;CX0,继续循环继续循环 MOV NUMBER, BL END START 例例设设STRING开始的区域中存放着一个字符串开始的区域中存放着一个字符串,以字符以字符* 作为结束标志。设计程序作为结束

29、标志。设计程序,统计字符串的长度统计字符串的长度,并存入并存入 LENGTH单元中。单元中。 解解:程序如下程序如下: START:MOV AX,DATA MOV DS,AX LEA BX,STRING ;设置字符串首地设置字符串首地 MOV CX,0 ;计数器清计数器清0 LOOP1:MOV AL,BX ;取一个字符取一个字符 CMP AL,* ;与与*比较比较 JZ LOOP2 ;相等转相等转LOOP2 INC CX ;计数器加计数器加1 INC BX ;修改指针修改指针 JMP LOOP1 ;循环循环 LOOP2: MOV LENGTH, CX ;存结果存结果 END START ;例:

30、内存缓冲区从例:内存缓冲区从BUF+1开始存有若干个单字节的开始存有若干个单字节的 有符号数,其个数放在有符号数,其个数放在BUF单元,要求找出单元,要求找出最大数最大数 送到送到MAX单元,最小数送到单元,最小数送到MIN单元单元。 DATA SEGMENT USE16 BUF DB 8, 34,56,-1,7FH,-88,200,22,80H MAX DB ? MIN DB ? DATA ENDS CODE SEGMENT USE16 ASSUME CS:CODE,DS:DATA BEG: MOV AX,DATA MOV DS,AX MOV CH,0 MOV CL,BUF MOV AL,B

31、UF+1 MOV MAX,AL MOV MIN,AL DEC CX MOV BX,OFFSET BUF+2 LAST:MOV AL,BX CMP AL,MAX JG GREAT CMP AL,MIN JL LESS JMP NEXT GREAT: MOV MAX,AL JMP NEXT LESS:MOV MIN,AL NEXT:INC BX LOOP LAST MOV AH,4CH INT 21H CODE ENDS END BEG 例在字型例在字型无序表无序表中找出中找出最大数最大数和和最小数最小数,并分别,并分别 存入存入MAX和和MIN单元。单元。 STACKSG SEGMENT STA

32、CK STK DW 32 DUP(S) STACKSG ENDS DATA SEGMENT BUFFER DW 500,30,56,77,999,67,433,5675,0,9999, 3455,6578,32766,8,0,32560,45,889,5665,09 ;无序表无序表 CN DW ($-BUFFER)/2;元素个数元素个数 MAX DW ?;存放最大数单元存放最大数单元 MIN DW ? ;存放最小数单元存放最小数单元 DATA ENDS CODE SEGMENT MAIN PROC FAR ASSUME CS:CODE,DS:DATA PUSH DS XOR AX,AX PUS

33、H AX MOV AX,DATA MOV DS,AX LEA SI,BUFFER ;初始化地址指针初始化地址指针 MOV CX,CN ;元素个数元素个数 MOV AX,SI ;取第一数取第一数 MOV MAX,AX ;初始化最大数初始化最大数 MOV MIN,AX ;初始化最小数初始化最小数 DEC CX ;循环次数减循环次数减1 COMP:ADD SI,2 ;修改地址指针修改地址指针 MOV AX,SI;取下一个数取下一个数 CMP AX,MAX;与当前的最大数比较与当前的最大数比较 JL NEXT;若小于转若小于转 MOV MAX,AX ;若大于则把此数作为最大数保存若大于则把此数作为最大

34、数保存 JMP SHORT LOP NEXT:CMP AX,MIN;与当前的最小数比较与当前的最小数比较 JG LOP;若大于转若大于转 MOV MIN,AX;若小于则把此数作为最小数保存若小于则把此数作为最小数保存 LOP: LOOP COMP;决定循环继续还是终止决定循环继续还是终止 RET MAIN ENDP CODE ENDS END MAIN 多重循环程序设计多重循环程序设计 例编制用软件延时例编制用软件延时200ms的程序。的程序。 假设,以下程序片段可以延时假设,以下程序片段可以延时10ms: DELAY10: MOV CX,2801 ;置循环次数置循环次数 WT: LOOP W

35、T 则延时则延时200ms只需把以上程序片段只需把以上程序片段循环循环20次次即即 可,如下所示:可,如下所示: DELAY PROC MOV BL,20;置外循环次数置外循环次数 DELAY10: MOV CX,2801;置内循环次数置内循环次数 WT: LOOP WT;内循环体、循环次数修改及循环控制内循环体、循环次数修改及循环控制 DEC BL;修改外循环次数修改外循环次数 JNZ DELAY10;外循环控制外循环控制 RET DELAY ENDP 5.5 子程序设计子程序设计 子程序子程序(即即:过程过程)是相对独立的程序,当程序中经常是相对独立的程序,当程序中经常 需要完成某一项操作

36、时,为了简化程序和阅读方便,需要完成某一项操作时,为了简化程序和阅读方便, 常常把完成某项操作的程序单独设计为一个子程序,常常把完成某项操作的程序单独设计为一个子程序, 需要时就调用它。需要时就调用它。 子程序通常用子程序通常用PROC/ENDP作为定界语句,用作为定界语句,用CALL 指令调用,子程序用指令调用,子程序用RET返回。返回。 从子程序相对于调用指令的位置来看,分为从子程序相对于调用指令的位置来看,分为段内段内和和 段间段间子程序。分别用子程序。分别用NEAR和和FAR表示其属性。表示其属性。 根据子程序入口地址给出的方式不同,子程序的调根据子程序入口地址给出的方式不同,子程序的

37、调 用也可以分为用也可以分为直接直接和和间接调用间接调用两种方式。两种方式。 1调用程序和子程序在调用程序和子程序在同一个代码段同一个代码段的程序结构的程序结构 (子程序类型可缺省,注意(子程序类型可缺省,注意END后必须跟主程序名)后必须跟主程序名) CODE SEGMENT MAINPROC FAR CALLSUB1 RET MAINENDP SUB1PROC RET SUB1ENDP CODEENDS ENDMAIN 2调用程序和子程序在调用程序和子程序在不同段不同段的程序结构的程序结构(SUB2既被既被段间段间调用又被调用又被段内段内 调用调用,必须是必须是FAR属性属性。CALL要显

38、式说明是要显式说明是FAR属性)属性) CODE1SEGMENT MAINPROC FAR CALLFAR PTR SUB2 RET MAINENDP CODE1ENDS CODE2SEGMENT SUB2PROC FAR RET SUB2ENDP SUB3PROC CALLFAR PTR SUB2 RET SUB3ENDP CODE2ENDS ENDMAIN 子程序分为无参数和有参数两种。子程序分为无参数和有参数两种。 调用有参数的子程序时,向子程序调用有参数的子程序时,向子程序传递参数的方法传递参数的方法 有三种:有三种: (1)利用利用寄存器寄存器。使用方便,适合于传递。使用方便,适合于

39、传递参数较少参数较少的的 场合;场合; (2)利用利用堆栈堆栈;例如:;例如:C语言中的动态存储区语言中的动态存储区 (3)利用利用内存单元内存单元。如果使用连续多个存储单元:实。如果使用连续多个存储单元:实 际上是传递一片连续存储单元的首地址指针,际上是传递一片连续存储单元的首地址指针, 即:把即:把首地址首地址的偏移地址放在某个的偏移地址放在某个寄存器寄存器里面。里面。 注意,若调用程序和子程序在注意,若调用程序和子程序在同一模块同一模块(源程序)(源程序) 中,子程序可以直接访问模块中的变量。中,子程序可以直接访问模块中的变量。 通常情况下,一个子程序或函数:通常情况下,一个子程序或函数

40、: 只有只有一个入口一个入口:调用子程序实际上是根据:调用子程序实际上是根据CS:IP指向指向 子程序子程序第一条第一条指令的地址;指令的地址; 可以有可以有多个出口多个出口(多条多条RET指令指令); 但返回主程序的同一个位置:但返回主程序的同一个位置:一个断点一个断点; 实际上,如果需要、子程序可以提供实际上,如果需要、子程序可以提供多个入口多个入口:此:此 时,调用子程序时可以从第二条、第三条指令开始时,调用子程序时可以从第二条、第三条指令开始 执行;执行; 类似地,通常、子程序返回时通常是返回到调用程类似地,通常、子程序返回时通常是返回到调用程 序的断点,即:序的断点,即:CALL指令

41、的下一条指令。但实际指令的下一条指令。但实际 上,如果需要、也可以上,如果需要、也可以不返回断点不返回断点(CALL的下一条的下一条 指令指令)、而是返回任意指定的位置、而是返回任意指定的位置。 理解:因为,无论是多个入口或多个出口或多个断理解:因为,无论是多个入口或多个出口或多个断 点,本质含义都是通过指令引导点,本质含义都是通过指令引导CPU根据指定的根据指定的 CS:IP的内容进行跳转。的内容进行跳转。 例例3个个16位操作数加法程序位操作数加法程序 解法解法1主程序通过主程序通过内存单元内存单元(把内存单元的首地址放把内存单元的首地址放 入入SI)传递参数给传递参数给COMPUTE,通

42、过通过寄存器寄存器BX直接直接 传递参数给子程序传递参数给子程序DISP显示结果。显示结果。 DATA SEGMENT USE16 NUM DW 1122H DW 3344H DW 5566H ;参数在存储单元中参数在存储单元中 DATA ENDS STACK_ SEGMENT STACK USE16 DB 100H DUP(?) STACK_ ENDS CODE SEGMENT USE16 ASSUME CS:CODE,DS:DATA,SS:STACK_ BEG:MOV AX,DATA MOV DS,AX MOV ,OFFSET NUM CALL COMPUTE ;BX中为中为3个数之和个数

43、之和 ;-COMPUTE-;参数在数据段参数在数据段(DS) ;入口参数:三个入口参数:三个16位加数放在内存位加数放在内存DS:SI开始处开始处 ;出口参数:出口参数:16位和放在位和放在BX中中 ;功能:完成三个功能:完成三个16位数相加位数相加 COMPUTE PROC NEAR MOV BX,0 ;累加和累加和 ADD BX,SI+0 ;加第一个数加第一个数 ADD BX,SI+2 ADD BX,SI+4 ;省略省略DS,参数在存储单元中,参数在存储单元中 RET COMPUTE ENDP CODE SEGMENT USE16 ASSUME CS:CODE,DS:DATA,SS:STA

44、CK_ BEG:MOV AX,DATA MOV DS,AX MOV ,OFFSET NUM CALL COMPUTE ;BX中为中为3个数之和个数之和 CALL DISP MOV AH,4CH INT 21H ;-DISPLAY ;将将BX中的数值以二进制中的数值以二进制 ASCII码显示到屏幕码显示到屏幕 DISP PROC NEAR MOV CX,16 LAST:MOV DL,0 RCL BX,1 JNC NEXT MOV DL,1 NEXT:MOV AH,2 INT 21H LOOP LAST RET DISP ENDP CODE ENDS END BEG 解法解法2主程序通过主程序通过

45、堆栈堆栈传递参数给子程序传递参数给子程序 COMPUTE DATA SEGMENT USE16 NUM DW 1122H ;加数加数N1 DW 3344H ;加数加数N2 DW 5566H ;加数加数N3 DATA ENDS STACK_ SEGMENT STACK USE16 DB 100H DUP(?) STACK_ ENDS CODE SEGMENT USE16 ASSUME CS:CODE,DS:DATA,SS:STACK_ BEG:MOV AX,DATA MOV DS,AX MOV SI,OFFSET NUM ;图示:图示:SP的变化的变化:初始为初始为SP0 PUSH WORD P

46、TR SI+0 ; SP0-2 、 1122H入栈入栈 PUSH WORD PTR SI+2 ; SP0-4 、 3344H入栈入栈 PUSH WORD PTR SI+4 ; SP0-6 、 5566H入栈入栈 CALL COMPUTE ; SP0-8(段内段内) 、断点入栈、断点入栈 XYZ: ;-COMPUTE-;参数在堆栈段参数在堆栈段(SS) ; 子程序子程序COMPUTE中:中:SP当前值当前值: SP0-8 ; 输入参数输入参数: 在在堆栈中的堆栈中的SS:SP0-8+2,SS:SP0-8+4, ;SS:SP0-8+6中:中:分别为分别为N3, N2, N1 COMPUTE PRO

47、C NEAR MOV BP,SP MOV BX,0 ;累加和累加和 ADD BX,BP+2;操作数在堆栈中操作数在堆栈中:N3 ADD BX,BP+4;操作数操作数N2 ADD BX,SS:BP+6;操作数操作数N1 RET 6; 堆栈恢复原状堆栈恢复原状:SP恢复恢复初始值初始值SP0 COMPUTE ENDP CODE SEGMENT USE16 ASSUME CS:CODE,DS:DATA,SS:STACK_ BEG:MOV AX,DATA MOV DS,AX MOV SI,OFFSET NUM ;图示:图示:SP的变化的变化:初始为初始为SP0 PUSH WORD PTR SI+0 ;

48、 SP0-2 、 1122H入栈入栈 PUSH WORD PTR SI+2 ; SP0-4 、 3344H入栈入栈 PUSH WORD PTR SI+4 ; SP0-6 、 5566H入栈入栈 CALL COMPUTE ; SP0-8(段内段内) 、断点入栈、断点入栈 XYZ:CALL DISP MOV AH,4CH INT 21H ;-DISPLAY DISP PROC NEAR MOV CX,16 LAST:MOV DL,0 RCL BX,1 JNC NEXT MOV DL,1 NEXT:MOV AH,2 INT 21H LOOP LAST RET DISP ENDP CODE ENDS

49、END BEG 解法解法3主程序仍然通过主程序仍然通过内存单元内存单元(内存单元的首地址内存单元的首地址 放入放入SI)传递参数给传递参数给COMPUTE。 注意:注意:断点断点的含义!的含义! CODE SEGMENT USE16 ASSUME CS:CODE,SS:STACK_ BEG: CALL COMPUTE ;将将OFFSET NUM值压入堆栈值压入堆栈 NUM DW 1122H ; CS段段图示:图示:数数N1 DW 3344H ; 数数N2 DW 5566H ; 数数N3 ;注意:注意:数据定义在代码段数据定义在代码段!(类似于类似于COM格式格式) ;理解:指令;理解:指令CA

50、LL COMPUTE的的断点断点是是下一个存下一个存 储单元的地址储单元的地址(内容是数据内容是数据22H) !且压入堆栈。!且压入堆栈。 此时:此时:断点断点指示的存储单元存放数据而指示的存储单元存放数据而不是指令不是指令! XYZ:CALL DISP ; CALL COMPUTE正确断点正确断点应该是应该是XYZ MOV AH,4CH INT 21H ;-COMPUTE-;参数在参数在代码段代码段(CS) COMPUTE PROC NEAR MOV BP,SP MOV SI,BP+0 ;SI栈顶栈顶OFFSET NUM MOV BX,0 ;初始和为初始和为0 ADD BX,CS:SI+0

51、; 加数加数N1;CS不能省略不能省略 ;理解:加数可以用理解:加数可以用CS:NUM寻址寻址 ADD BX,CS:SI+2 ; 加数加数N2 ADD BX,CS:SI+4 ; 加数加数N3 POP AX ;将栈顶元素将栈顶元素OFFSET NUM值抛弃值抛弃 MOV AX,OFFSET XYZ PUSH AX ;把真正的断点把真正的断点OFFSET XYZ压入堆栈压入堆栈 RET ;弹出断点弹出断点IP,返回主程序返回主程序XYZ处处 COMPUTE ENDP ;-DISPLAY DISP PROC NEAR ; 显示显示BX中各个二进制位中各个二进制位 MOV CX,16 LAST:MOV

52、 DL,0 RCL BX,1 JNC NEXT MOV DL,1 NEXT:MOV AH,2 INT 21H LOOP LAST RET DISP ENDP CODE ENDS END BEG 【例例4.31】设设NUM开始的单元中存放着开始的单元中存放着10个个无符号无符号字型字型数组数组 元素元素,利用利用子程序子程序求出该数组中求出该数组中最大值最大值与与最小值最小值,分别存入分别存入 MAX和和MIN单元中。单元中。 解解:说明文件及程序如下说明文件及程序如下: 子程序名子程序名:MAX_MIN 子程序功能子程序功能:求数组中的最大值与最小值。求数组中的最大值与最小值。 入口参数入口参

53、数:SI存放存放数组首地址数组首地址,CX存放存放数组元素个数数组元素个数。 出口参数出口参数:最大数存入最大数存入MAX单元单元,最小数存入最小数存入MIN单元单元。 子程序用到的寄存器子程序用到的寄存器:SI、CX、AX和和BX 程序代码如下程序代码如下: DATA SEGMENT NUM DW 980,435H,4,547DH,1234H,320H,456H,7890H,234,128 MAX DW ? MIN DW ? DATA ENDS STACK SEGMENT STACK DW 256 DUP(?) TOP LABEL WORD ;TOP为字地址为字地址 STACK ENDS C

54、ODE SEGMENT ASSUME CS:CODE,DS:DATA,SS:STACK MAIN: MOV AX, DATA MOV DS, AX MOV AX, STACK MOV SS, AX MOV SP, OFFSET TOP LEA SI, NUM ;SI指向数据缓冲区指向数据缓冲区第一个第一个数组元素数组元素 MOV CX, 9 ;剩余剩余9个个元素需要比较元素需要比较 CALL MAX_MIN MOV AH,CH ;AH00 INT 21H ;返回返回DOS MAX_MIN PROC NEAR PUSH AX PUSH BX PUSH CX PUSH SI MOV AX,SI ;

55、最大数最大数 MOV BX,AX ;最小数最小数 LOPX: ADD SI , 2 CMP SI , AX ; 与较大的与较大的AX比较比较 JC MINU ; 如果小于较大的如果小于较大的AX, 则继续与较小的则继续与较小的BX比比 较较 JZ NEXT;等于;等于AX MOV AX,SI;大于大于AX JMP NEXT;能否省略能否省略 MINU: CMP SI,BX JNC NEXT ;大于大于BX MOV BX,SI;小于小于BX NEXT: LOOP LOPX MOV MAX,AX ;保存较大数保存较大数 MOV MIN,BX ;保存较小数保存较小数 POP SI POP CX PO

56、P BX POP AX RET MAX_MIN ENDP CODE ENDS END MAIN 设计子程序时应注意的问题:设计子程序时应注意的问题: 1子程序说明;子程序说明; 2寄存器的保存与恢复;寄存器的保存与恢复; 3密切注意堆栈状态。密切注意堆栈状态。 若调用程序和子程序在若调用程序和子程序在同一模块同一模块中,子程序可以直中,子程序可以直 接访问模块中的变量。接访问模块中的变量。 例实现例实现数组求和数组求和功能。要求数组求和(不考虑溢功能。要求数组求和(不考虑溢 出情况)由子程序实现,其数组元素及结果均为字出情况)由子程序实现,其数组元素及结果均为字 型数据。型数据。 STACKS

57、G SEGMENT STACK STK DW 32 DUP(S) STACKSG ENDS DATA SEGMENT ARY DW 1,2,3,4,5,6,7,8,9,10 COUNT DW ($-ARY)/2;数组元素个数数组元素个数 SUM DW ?;数组和的地址数组和的地址 DATA ENDS CODE1 SEGMENT MAIN PROC FAR ASSUME CS:CODE1,DS:DATA PUSH DS XOR AX,AX PUSH AX MOV AX,DATA MOV DS,AX CALL FAR PTR ARY_SUM RET MAIN ENDP CODE1 ENDS COD

58、E2 SEGMENT ASSUME CS:CODE2 ARY_SUM PROC FAR;数组求和子程序数组求和子程序 PUSH AX;保存寄存器保存寄存器 PUSH CX PUSH SI LEA SI,ARY;取数组起始地址取数组起始地址 MOV CX,COUNT;取元素个数取元素个数 XOR AX,AX;清清0累加器累加器 NEXT: ADD AX,SI;累加和累加和 ADD SI,TYPE ARY;修改地址指针修改地址指针 LOOP NEXT MOV SUM,AX;存和存和 POP SI;恢复寄存器恢复寄存器 POP CX POP AX RET ARY_SUM ENDP CODE2 END

59、S END MAIN 通过通过地址表地址表传递参数地址传递参数地址 适用于参数较多的情况。具体方法是先建立适用于参数较多的情况。具体方法是先建立 一个地址表,该表由参数地址构成。然后把一个地址表,该表由参数地址构成。然后把 表的首地址通过寄存器或堆栈传递给子程序。表的首地址通过寄存器或堆栈传递给子程序。 例编写一个数组求和子程序,其数组元素例编写一个数组求和子程序,其数组元素 及结果均为字型数据。另定义两个数组,并及结果均为字型数据。另定义两个数组,并 编写一个主程序,通过调用数组求和子程序编写一个主程序,通过调用数组求和子程序 分别求出两个数组的和。分别求出两个数组的和。 STACKSG S

60、EGMENT STACK STK DW 32 DUP(S) STACKSG ENDS DATA SEGMENT ARY DW 1,2,3,4,5,6,7,8,9,10 ;数组数组1 COUNT DW ($-ARY)/2;数组数组1的元素个数的元素个数 SUM DW ?;数组数组1的和地址的和地址 NUM DW 10,20,30,40,50;数组数组2 CT DW ($-NUM)/2;数组数组2的元素个数的元素个数 TOTAL DW ?;数组数组2的和地址的和地址 TABLE DW 3 DUP(?);地址表地址表 DATA ENDS CODE1SEGMENT MAINPROC FAR ASSUM

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论