230 likes | 416 Views
第 4 章 汇编语言程序设计. 【 本章重点 】 熟练掌握汇编语言的四种程序设计方法: 顺序程序设计,分支程序设计,循环程序 设计以及子程序设计。 【 本章难点 】 确定算法,合理分配内存工作单元。. §4.1 汇编语言程序设计概述. 4.1.1 汇编语言程序设计步骤 使用汇编语言设计一个程序大致上可分为以下几个步骤。 (1) 分析问题,明确要求。解决问题之前,首先要明确所要解决的问题和要达到的目的、技术指标等。
E N D
第4章 汇编语言程序设计 【本章重点】熟练掌握汇编语言的四种程序设计方法: 顺序程序设计,分支程序设计,循环程序 设计以及子程序设计。 【本章难点】确定算法,合理分配内存工作单元。
§4.1 汇编语言程序设计概述 4.1.1 汇编语言程序设计步骤 使用汇编语言设计一个程序大致上可分为以下几个步骤。 (1) 分析问题,明确要求。解决问题之前,首先要明确所要解决的问题和要达到的目的、技术指标等。 (2) 确定算法。根据实际问题的要求、给出的条件及特点,找出规律性,最后确定所采用的计算公式和计算方法,这就是一般所说的算法。算法是进行程序设计的依据,它决定了程序的正确性和程序的指令。 (3) 画程序流程图,用图解来描述和说明解题步骤。
(4) 分配内存工作单元,确定程序与数据区的存放地址。 (5) 编写源程序。 (6) 程序优化。 (7)程序调试、修改和最后确定源程序。只有通过上机调试并得出正确结果的程序,才能认为是正确的程序。没有调试过的程序,很难保证程序无错误,程序调试是不可缺省的。
§4.2顺序程序设计 对于一些简单的数据处理,只要把完成处理的各个步骤用汇编语言描述清楚,让计算机按指令编写的次序从头到尾一条条执行即可,这样的程序结构称为顺序结构。 【例4-1】已知X和Y是数据段中的两个无符号字节单元,用程序完成表达式Z=(X2+Y2)/2的计算。 编制程序如下:
DATA SEGMENT X DB 15 Y DB 34 Z DW ? DATA ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA START: MOV AX,DATA MOV DS,AX ;初始化数据段 MOV AL,X ;X中的内容送AL MUL AL ;计算X×X MOV BX,AX ;X×X乘积送BX MOV AL,Y ;Y中的内容送AL MUL AL ;计算Y×Y ADD AX,BX ;计算X2+Y2 SHR AX,1 ;计算(X2+Y2)/2 MOV Z,AX ;结果送Z单元 MOV AH,4CH INT 21H ;返回DOS CODE ENDS END START ;汇编结束
【例4-2】从键盘读入两个一位数(按键时保证按下的是数字键),显示它们的积。【例4-2】从键盘读入两个一位数(按键时保证按下的是数字键),显示它们的积。 先后从键盘上读取两个按键,分别减去30H得到它们对应的数值,然后相乘分解成十位数字与个位数字,转换成ASCⅡ码后依次输出即可。为了输入输出效果的直观,有必要在每次按键后回车换行。 CODE SEGMENT ASSUME CS:CODE MAIN: MOV AH,1 INT 21H ;读入第1个数字 MOV BL,AL ;保存在BL中 MOV AH,2 MOV DL,13 INT 21H ;回车 MOV DL,10 INT 21H ;换行
MOV AH,1 INT 21H ;读入第2个数字 SUB AL,30H ;第2个数字转换成十进制数 SUB BL,30H ;第1个数字转换成十进制数 MUL BL ;两个数相乘,积在AX中 MOV BL,10 ; DIV BL ;积除以10取商送AL,余数在AH中 ADD AX,3030H ;转换成相应的ASCⅡ码 MOV BX,AX ;保存在BX中 MOV AH,2 MOV DL,13 INT 21H ;回车 MOV DL,10 INT 21H ;换行 MOV DL,BL MOV AH,2 INT 21H ;输出十位数 MOV DL,BH INT 21H ;输出个位数 MOV AH,4CH INT 21H ;返回DOS CODE ENDS END MAIN ;程序结束
§4.3分支程序设计 分支程序是利用条件转移指令,使程序执行到某一指令后,根据条件是否满足,来改变程序执行的次序。在程序设计中经常会遇到各种判断和比较,例如“相等”和“不相等”;“正”和“负”;“大于”和“小于”;“满足条件”和“不满足条件”等等,这些判断和比较在程序中都可以组成各种不同的逻辑框,并产生相应的分支程序。
【例4-3】已知AX中放有一个带符号数,编写程序段,计算它的绝对值。【例4-3】已知AX中放有一个带符号数,编写程序段,计算它的绝对值。 ┇ CMP AX,0 JGE LOOP MOV BX,AX MOV AX,0 SUB AX,BX LOOP: ┇ ┇
1 当X>0 【例4-4】符号函数Y= 0 当X=0 (-128≤X≤+127) -1 当X<0 设任意给定的X存放在XX单元,计算出函数Y值要求存放在YY单元。
TA SEGMENT XX DB 0F0H YY DB ? DATA ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA START PROC FAR PUSH DS SUB AX,AX PUSH AX MOV AX,DATA MOV DS,AX MOV AL,XX CMP AL,0 JGE BIGR MOV AL,0FFH MOV YY,AL RET BIGR: JE EQUL MOV AL,1 EQUL: MOV YY,AL RET START ENDP CODE ENDS END START
§4.4循环程序设计 循环程序是强制CPU重复执行某一指令系列的一种程序结构形式,它可以使许多重复工作的程序大为简化,而且减少内存空间。被重复执行的部分称作循环体,要想把循环体多次执行,就必须在循环体的前后有相应的指令实现循环控制。 循环程序一般由4部分组成: 初始化、循环体、循环控制和循环结束处理
循环程序分为单循环和多重循环,两重以上循环称为多重循环循环程序分为单循环和多重循环,两重以上循环称为多重循环
【例4-5】现将以AREA1为首地址的100个字节数据搬移到以AREA2为首地址的内存中去。【例4-5】现将以AREA1为首地址的100个字节数据搬移到以AREA2为首地址的内存中去。 程序如下: AGAIN: MOV AL,[SI] MOV [DI],AL INC SI INC DI DEC CX JNZ AGAIN MOV AH,4CH INT 21H CODE ENDS END START DATA SEGMENT AREA1 DB 100DUP(?) ATEA2 DB 100DUP(00) DATA ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA START:MOV AX,DATA MOV DS,AX MOV SI,OFFSET AREA1 MOV DI,OFFSET ATEA2 MOV CX,100
【例4-6】若有一串无符号数,放在NUM开始的单元中,要求编制汇编语言程序,将其中的最大值找出来,且放到存储单元MAX中,这串数的长度已存放在COUNT单元。【例4-6】若有一串无符号数,放在NUM开始的单元中,要求编制汇编语言程序,将其中的最大值找出来,且放到存储单元MAX中,这串数的长度已存放在COUNT单元。 程序如下: DATA SEGMENT COUNT DW 20 NUM DW a1,a2,a3,….a20 MAX DW ? DATA ENDS STACK SEGMENT PARA STACK ‘STACK’ DB 20DUP(?) STACK ENDS CODE SEGMENT ASSUME CS:CODE,DS:DATA,SS:STACK
MAIN PROC FAR PUSH DS MOV AX,0 PUSH AX MOV AX,DATA MOV DS,AX MOV BX,OFFSET NUM MOV CX,COUNT MOV AX,[BX] INC BX INC BX LOOP1: CMP AX,[BX] JAE LOOP2 MOV AX,[BX] LOOP2: INC BX INC BX DEC CX JNZ LOOP1 MOV [MAX],AX RET MAIN ENDP CODE ENDS END MAIN
【例4-7】设计一个100ms的软件延时程序。采用多重循环程序,内循环完成10ms的延时,外层循环10次即可。【例4-7】设计一个100ms的软件延时程序。采用多重循环程序,内循环完成10ms的延时,外层循环10次即可。 程序如下: CODE SENGMET ASSUME CS:CODE START: MOV DL,10 DELAY1: MOV CX,2800H DELAY2: LOOP DELAY2 DEC DL JNZ DELAY1 MOV AH,4CH INT 21H CODE ENDS END START
§4.5子程序设计 1.子程序格式 子程序格式如下: 子程序名 PROC 类型 指令序列 子程序名 ENDP 2.子程序调用与返回 子程序调用与子程序返回由CALL和RET指令实现。子程序调用方式有近程调用、远程调用、直接调用和间接调用。
指令格式:CALL 子程序名 指令功能:这是调用子程序的指令。根据被调用的子程序的类型不同,CALL指令的功能分为两种情况: (1)近程调用(段内调用),类型为NEAR,调用时首先把当前IP值压入堆栈,而后执行子程序,当子程序执行完后,利用RET指令将堆栈中保护的IP值弹出IP寄存器,完成一次近程调用过程。 (2)远程调用(段间调用),类型为FAR,调用时先把CS压入堆栈,再把IP压入堆栈。尔后执行子程序,当子程序执行完后,利用RET指令堆栈中保护的程序弹出IP寄存器和CS段寄存器中。完成一次远程的调用过程。
3.保护现场和恢复现场 利用指令PUSH保护现场,利用指令POP恢复现场。 例如:SUB1 PROC NEAR PUSH AX 保护现场 PUSH BX PUSH CX PUSH DX ┇ ┇ POP DX 恢复现场 POP CX POP BX POP AX RET SUB1 ENDP
主程序 子程序 MAIN: ┇ SUBR PROC NEAR ┇ ┇ MOV DI,OFFSET DATA1 MOV AX,BX MOV SI,OFFSET DATA2 ┇ MOV BX,[SI] 结果 →BX CALL SUBR RET MOV [DI],BX SUBR ENDP 4.主程序和子程序之间的参数传送方法 主程序在调用子程序时,经常需要传送一些参数给子程序;子程序运行完后经常要回送一些信息给主程序。这种主程序和子程序之间的信息传送称为参数传送的主要方法有以下几种: (1)通用寄存器传送参数 例如:用寄存器BX完成主程序→子程序的参数传送,并由子程序将BX带回→主程序。
(2)存储单元传送参数 若主程序和子程序在同一程序段中,则子程序可直接访问主程序数据段中的参数。换名说就是主程序和子程序同时可访问同一数据段中的数据或地址。 (3)通过堆栈传送参数 主程序与子程序传递参数时,可以把要传递的参数放在堆栈中,这些参数既可以是数据,也可以是地址。具体方法是在调用子程序前将参数送入堆栈,在子程序中通过出栈方式取得参数,执行完毕后再将结果依次压入堆栈。返回主程序后,通过出栈获得结果。