1、 第四章 汇编语言程序设计4.1 程序设计语言4.1.1 机器语言以二进制代码形式表示指令和数据的语言.(机器码)如 00111010 + 01011100 30H其机器语言程序为 符号语言程序二进制 十六进制 01110100 74H MOV A, #3AH00111010 3AH00100100 24H ADD A, #5CH01011100 5CH11110101 F5H MOV 30H, A00110000 30H计算机能够识别机器语言,并能够按设计好的逻辑执行这一串代码所规定的动作.但这种语言难懂、难记、易错和编程困难。借助助记符形成符号语言,反映指令功能和主要特征,这样便于理解和记
2、忆,这就形成汇编语言。4.1.2 汇编语言用符号来表示指令和地址的语言就称作符号语言,又称作汇编语言。这也是一种面向机器的语言。 汇编语言的符号往往用人们容易辨认、阅读和记忆的字母符号。()助记符:指令系统,如加法 ADD,减法 SUB(TRACT),传送 MOV(E)伪指令,这是汇编控制指令()符号地址和标号:用一些便于、记忆和理解的符号组,如 LOOP、NEXT 汇编() 几个概念源程序: 用符号语言编写的程序。目标程序:机器能够直接执行的机器语言程序。把源程序翻译成目标程序的过程就称作 汇编,又称作 代真。() 汇编方法人工查表 人工汇编: 源程序目标程序要求一丝不苟,认真细致,繁琐且易
3、出错。汇编程序 机器汇编: 源程序目标程序汇编语言程序 机器语言程序准确、快速,不会出偶然性错误()汇编类型 自汇编:机器本身完成的汇编过程,又称驻留汇编。 交叉汇编:用其他机器将程序变成目标程序后送回机器执行。 反汇编:将目标程序变回汇编语言程序。! 汇编语言程序与汇编程序是两个不同的概念,不能混淆。汇编语言虽然比机器语言前进了一大步,但它还是面向机器的一种语言,不同的机器就要有不同的汇编语言,要用汇编语言编写程序,就必须对该种计数器十分熟悉(包括指令系统以至于硬件情况),而且编写出的程序只能在这种机器上使用。有没有不依赖或少依赖机器的语言呢?这就是高级语言。4.1.3 高级语言只与解决问题
4、的算法有关,而与机器的类型、结构和指令系统无关。面向过程的语言:科学计算: FORTRAN、ALGOL、PASCAL、BASIC、C商业管理: COBOL数字程控: APT人工智能: LISP、PROLOG面向对象的语言:Smalltalk、C+、Visual BASIC 、Visual C+(1) 优点不依赖(很少)依赖于机器,学习容易,变成效率高,使用方便,程序短,便于交流和推广。可移植性好,同一个程序可以在不同的机器上运行。(2) 缺点语法复杂,特殊规定多用高级语言编写的程序要经过编译程序(Compiler)或解释程序(Interpreter)翻译成目标程序才能运行。而高级语言的编译开销
5、大,要有大量的硬件和软件支持,需要占用大量内存,高级语言越复杂,功能越强,编译程序越庞大(从几k到几M);运行效率低,一般要膨胀15300。4.1.4 使用汇编语言的意义 高级语言的编译程序大多是用汇编语言编写 汇编语言的运行效率高,提高了计算机的效率,这在实时控制应用中特别重要。 对专用程序、重复使用频率高的程序应该用汇编语言编写,更加有利于提高效率。 采用汇编语言可以充分发挥机器的专有特性。 硬件成本低和软件投资少。 搞通汇编语言,有助于理解和评价高级语言。4.1.5 结论 使用机器语言和汇编语言无需太多的软件和硬件支持,而且能产生质量很高的目标程序,但成程序没有通用性,难编难懂。总的来说
6、,汇编语言开发效率低,运行效率高。 高级语言面向过程和面向对象,不依赖于个别的机器,程序相对易编易懂,便于交流使用,但需要较多的软件和硬件支持,而且产生的程序相对质量较低,所占用的时间和空间都大,时空指标下降,一般不适用于实时响应。总的来说,高级语言开发效率高,运行效率低。4.2 MCS-51系列单片机汇编语言4.2.1 汇编语言源程序格式指令助记符符号由厂方设计人员规定。符号地址由用户自己确定。典型的汇编语言语句结构由四部分组成:标号: 操作码 操作数 ; 注解(Lable) (Opcode) (Operand) (Comment)标号后面用冒号分隔,操作码与操作数之间用空格分隔,操作数之间
7、用逗号分隔,操作数与注解之间用分号分隔。 标号:指令的符号地址,在程序汇编时,就被赋以指令存储地址的具体数值。采用符号地址便于查看、修改,尤其是转移指令中转移地址的表示。实际上并不是每条指令都需要加上标号,只有要被其他语句引用的指令才需要加上标号。标号有如下规定:() 由字母、数字和其他一些字符组成,但为了在汇编时与数据区分,要求第一个符号必须是大写字母。所用字符一般不超过6个。() 标号不能用操作码的助记符和寄存器的代号以及其他系统保留字。() 特定的标号只能在程序中定义一次,保持一义性。请大家对以下几个标号进行判断,看是否合法:NEXT2 3AB LOOP3 M3 ADD DPTR B3G
8、K4D SP COUNTER -AZ nmpq 操作码字段这一字段永远不会是空的。(其他三个字段有时会是空的)() 指令系统的助记符(硬指令),即指令操作码助记符。在汇编时,与“操作码表”进行逐一比较,找出其相应的机器码代真。() 伪指令(软指令),这是汇编过程的控制指令,也是汇编程序的操作指令。与指令系统的助记符不同,没有机器码与它对应,当源程序汇编成目标程序后,目标程序中并不出现这些伪指令的代码,它们仅在汇编过程中起作用,完成一些特定的操作。 操作数字段操作对象的数据值或以符号表示的数据或地址值。形式可以是工作寄存器、专用寄存器、已用伪指令EQU赋值的标号、用引号表示的ASCII码、立即数
9、(二进制、八进制、十进制和十六进制)和表达式。 注释字段用来对程序作一些注解和说明,便于人们阅读程序,汇编程序对此字段不予处理。在些注释时,一般说明指令的作用和执行的条件,注意要说明程序在做什么,而不是说明该指令在做什么。在用到子程序时,要说明子程序的入口条件和出口条件以及该程序完成的功能和作用。4.2.2 伪指令这是用来向汇编程序提供的有关如何完成汇编的控制命令信息。一旦汇编结束,伪指令的使命就完成,所以在目标程序中并不出现伪指令的代码。 ORG (Origin) 起点形式:标号: ORG 地址作用:指明此语句后面的程序或数据块存放区的首址。在一个程序中可以根据情况多次使用。其中标号是选择项
10、,根据需要选用,地址可以是16位的地址值,也可以是已赋值的标号和表达式。如 ORG 2000H 首地址为2000HORG 100 首地址为0064HORG BEGIN 在使用前要给BEGIN赋值ORG 首地址为0000H DB或DEFB (Define Byte) 定义字节形式:标号 DB 8位数表作用:把8位数表中的数值或字符的ASCII码存入从标号开始的连续存储单元中。其中8位数表是指一个字节或用逗号分开的字节串和引号内的ASCII码。如 ORG 2400HFIRST:DB 56H,0A3H ;56H、0A3H分别存放在2400H和2401H单元WORD:DB -3,5*2 ;FDH和0A
11、H存放在2402H和2403H单元中STR:DB TIME ;TIME的ASCII码54H、49H、4DH和45H存放在2404H、 ;2405H、2406H和2407H单元中 DW或DEFW (Define Word) 定义字(主要用于定义地址)形式:标号 DW 16位数表作用:把16位数表中的数值或字符的ASCII码存入从标号开始的连续存储单元中。如 ORG 2400HADDR:DW 56A3H ;56H、A3H分别存放在2400H和2401H单元DW AB ;41H、42H分别存放在2402H和2403H单元 DS或DEFS (Define Storage) 定义存储器形式:标号 DS
12、8位数表作用:由标号所指单元开始,保留指定的内存单元(字节)个数,以供源程序在运行中使用。如 ORG 3000HMAX:DS 1 ;保留3000H单元供存放“最大数”用BUF:DS 10 ;从3001H单元开始保留10个单元作缓冲区 EQU (Equate) 等值形式: 标号: EQU 赋值项作用: 使等式两边的8位量等值,赋值后在程序中不能改变。如 FIRST:EQU 20H ;给符号地址赋值为20HFIRST:EQU SECOND ;SECOND与FIRST等值,可在使用中互换 EQW (Equate Word) 字等值形式: 标号: EQW 赋值项作用: 使等式两边的16位量等值,赋值后
13、在程序中不能改变。如 FIRST:EQU 2200H ;给符号地址赋值为2200HFIRST:EQU SECOND ;SECOND与FIRST等值,可在使用中互换 BIT 位定义形式: 标号:BIT 8位位地址作用:给标号赋以位地址,该地址可以是直接地址,也可以是符号地址或位名如 USR-FLG:BIT F0/PSW.5 USR_FLG:BIT 0D5H END 结束汇编形式: 标号: END 表达式作用:通知汇编程序该汇编语言程序结束() 在一个源程序中必须要有END伪指令。而且只能有一个放在整个程序的最后;() 标号只有在其他指令要引用它时才需要;() 表达式一般在主程序中才需要,且表达式
14、即为主程序的起始地址,表示结束源程序的汇编,如果汇编正确,便自动地转向此首址的目标程序执行。如 MOV R0,#60H ORG 2000HMOV A,#3AH SUM:EQU 60HMOV B,#0AH NUMBA:EQU 3AHMUL AB NUMBB:EQU 0AHMOV R0,B MOV R0,#SUMINC R0 MOV A,#NUMBAMOV R0,A MOV B,#NUMBBMUL ABMOV R0, BINC R0MOV R0, AEND4.3 汇编语言程序设计4.3.1 简单直线程序 顺序程序例 多字节数加法两个三字节无符号数加法,一个加数在片内RAM的50H、51H、52H单
15、元中,另一个加数在53H、54H、55H单元中,要求相加之和存放在53H、54H、55H、56H单元中。MOV R0,#50HMOV R1,#53HMOV A,R0ADD A,R1MOV R1, AINC R0INC R1MOV A,R0ADDC A,R1MOV R1, AINC R0INC R1MOV A,R0ADDC A,R1MOV R1, ACLR AADDC A,#00HMOV R1, A 查表程序查表程序常用于数据补偿、非线性修正、求非线性函数和代码转换等。这种方法既不需要计算,速度又快,而且实现容易。如果在程序中不能用几条指令直接完成算术运算时,往往用查表法实现比较有利。但在表中必
16、须列出所有可能的值。所以这种方法需要占用较大的存储器空间。其实质是用空间换取时间。使用查表法的技巧在于巧妙地确定索引值,用得恰当可以大大简化程序设计,带来很大方便。特点:程序简单,执行速度快;在表中要列出所有可能的值,占用存储器较多,用空间换取时间。方法: (),根据变量在表中找到相应的值。表的形成也可用折线来分段,其中间值可通过插值方法计算。例 热敏电阻上的电压与所测的温度值为非线性关系。若用10位A/D对其电压进行采样,然后通过转换显示其温度值。这里把所测的10位二进制输入值与其相对应的温度值列成表格TTAB。测量的10位输入值x存放在R2和R3中,查表所得到的温度值也存放在R2和R3中。
17、10位二进制输入值的范围为0000H03FFH,一共有1024项,其分辨率为1/1024(0.1)! 这里表的偏移量(索引值)有两个字节,所以不能用A作为变址寄存器。VCT:MOV DPTR,#TTAB ;指向表格的首址MOV A, R3 ;以下计算R2R3+DPTRADD A, DPL ;R3+DPLMOV DPL, AMOV A, DPHADDC A, R2 ;R2+DPHMOV DPH, A ;DPTR指向温度的高字节CLR AMOVC A, A+DPTR ;读温度的高字节MOV R2, ACLR AINC DPTR ;DPTR指向温度的低字节MOVC A, A+DPTR ;读温度的低字
18、节MOV R3, ARETTTAB:DW XXXX ;温度值表DW XXXX例 键入一个ASCII字符,按不同的输入命令字符而转去执行相应的处理程序。设有六个命令字符“I”(输入)“D”(删除)“S”(存储)“C”(复制)“P”(打印)“T”(转换),对应的处理程序入口标号地址分别为AI、AD、AS、AC、AP、AT,用0作为表格的结束符。命令字符在Acc中。CCP:MOV DPTR, #CATABMOV B, A ;命令字符暂存于B中LOOP:CLR AMOVC A, A+DPTR ;取命令项XJZ CEND ;在表中未找到该命令项,转出错处理INC DPTR ;指向地址项YCJNE A,
19、B, NEXT ;若不是该命令,转调整指针继续查找CLR AMOVC A, A+DPTR ;若是该命令,取出其入口地址的高8位MOV B, A ;暂存于BINC DPTR ;指向入口地址的低8位CLR AMOVC A, A+DPTR ;取出入口地址的低8位MOV DPL, AMOV DPH, B ;入口地址送DPTRCLR AJMP A+DPTRNEXT:INC DPTR ;调整指针,指向下一个命令项INC DPTRSJMP LOOPCEND:容错或出错处理程序CATAB:DB “I“ 49HDW AIDB “D“ 44HDW ADDB “S“ 53HDW ASDB “C“ 43HDW ACD
20、B “P“ 50HDW APDB “T“ 54HDW AT 代码转换程序例 8位二进制数转换成BCD数分析:8位二进制数最大为255,是百位数,要用三位表示,而一个字节的BCD数只能表示小于100的两位数,所以转换结果要用两个字节单元来存放。思路:先除以100,商即为百位数,余数再除以10,商即为十位数,余数即为个位数。若要转换的8位二进制数在Acc中,要求转换后的BCD数存放在片内RAM的60H、61H和62H中。BCD1:MOV R0, #60H ;MOV B, #100 ;除数DIV AB ;(A)=百位数,(B)=余数MOV R0, A ;存放百位数INC R0 ;指向下一个单元MOV
21、 A, #10 ;10是除数,B中是余数(被除数)XCH A, B ;(A)=余数,(B)=10DIV AB ;(A)=十位数,(B)=个位数SWAP A ;十位数移至高4位ADD A, B ;个位数加到低4位MOV R0, A ;十位数和个位数存入下一个单元RET例 一位16进制数转换成ASCII码。一位16进制数在Acc中,其相应的ASCII码存放在60H单元。HEXASC:MOV R0, #60HANL A, #0FH ;取低4位ADD A, #02MOVC A, A+DPTRPC MOV R0, ARETASCTAB:DB 0,1,2,3,4DB 5,6,7,8,9DB A,B,C,D
22、,E,F一种简单而快速的算法:ADD A, #90HDA AADDC A, #40HDA ARET4.3.2 分支程序相当于高级语言中的IF-THEN条件语句,由于条件转移指令可根据条件是否满足来改变程序的执行顺序,凡是有判断与比较的地方都可以形成不同的程序分支。典型的分支程序框图编好分支程序的关键是掌握好标志的变化,使 程序能正确转移.同一个数若用不同的标志位作为程序转移的判断条件,那么该数就具有不同的含义。 单分支程序片内RAM两个单元ONE和TWO中存放有两个无符号数,将其中一个大数存放到MAX单元。MOV A, ONE ;将第一个数送AccCJNE A, TWO, BIG ;第一个数与
23、第二个数进行比较SJMP STORE ;若两数相等,就存放第一个数BIG: JNC STORE ;无借位,第一个数第二个数MOV A, TWO ;有借位,第一个数第二个数STORE: MOV MAX, A ;大数存入MAX单元 多分支程序散转程序这是一种需要根据某种输入或运算结果分别转向各个不同的处理程序的程序结构。其一般结构框图如下:例 利用地址偏移量表实现(如转向程序在同一页(256字节)内)按照R2的内容(00H03H)分别转向4个不同的处理程序。JMPN: MOV A, R2MOV DPTR, #JTABMOVC A, A+DPTRJMP A+DPTR1500H JTAB: DB PR
24、OG1-JTAB /20H1502H DB PROG2-JTAB /60H1504H DB PROG3-JTAB /A0H1506H DB PROG4-JTAB /D0H1520H PROG1: 处理程序1560H PROG2: 处理程序15A0H PROG3: 处理程序15D0H PROG4: 处理程序例 使用转移指令表,最大可有128个分支转移程序根据R2的内容(00H7FH),转向各个不同的处理程序。JMP128: MOV A, R2RL A / ADD A, R2 ;(R2)X2MOV DPTR, #JTABJMP A+DPTRJTAB: AJMP PROG1 ;转移程序必须在同一个2
25、k存储区内AJMP PROG2AJMP PROGN若转移程序不在同一个2k范围内 可用以下指令实现再转移:PROG1: LJMP XPRG1PROG2: LJMP XPRG2.PROGN: LJMP XPRGN 也可把转移指令表中的转移指令AJMP改用长转移指令LJMP,转移程序可以转向任一个地方,但这时索引值为(R2)X34.3.3 循环程序如果要对一组数据进行操作,并且这种操作是相同的,需要多次重复进行,这就可以用循环程序来实现。方法:用计数器来记录重复操作的次数或用地址指针来描述所处理数据在数组中的位置,也可根据某一条件是否满足来决定是否继续循环,从而控制循环重复操作的进行或结束。循环结
26、构相当于高级语言中的循环语句REPEAT-UNTIL或WHILE-DO.循环结构实际上也是一种分支程序结构,所不同的是分支结构的分支都是向下转移,而循环结构则有一个分支是向上转移,重复执行某一循环体。典型的循环程序流程图有两种:(1) 先执行,后判断 (2) 先判断,后执行相当于 repeat-until 相当于 while-do处理部分至少执行一次, 在计数初值为0时,处理部分就不执行看起来自然一些,似乎更符合习惯 适应性更强、更有效,但看起来别扭! 循环程序一定要安排出口,否则就得无限制地循环下去死循环 初始化部分:建立计数器、地址指针及其他变量的初值循环结束条件初值 循环工作部分初值 处
27、理部分(循环体):进行实际数据处理工作 循环控制部分:为下一轮处理修正计数器(计数器减1)和地址指针(地址指针加1),并检测循环结束条件,以决定下一步的去向。 结束部分:分析和存放结果一般第一部分和第四部分只执行一次,而第二部分和第三部分则需要重复执行多次,所以第二和第三部分程序的质量对整个程序有决定性影响,为提高整个程序的执行速度,就应着重减少第二和第三部分程序段的执行时间。 单循环程序 例 对一个32个单元的数据缓冲区(30H4FH)清零CLRBUF:MOV R0, #30HMOV R7, #20HCLR ALOOP:MOV R0, AINC R0DJNZ R7, LOOP例 计算若干数据
28、的和n 0 0 i i i-1 + i i1ni=1 如 i 都为单字节数,可依次存放在片内RAM从50H开始的单元内,n放在R2中,和放在R3R4中。ADDSUM:MOV R3, #00HMOV R4, #00H ;和单元清零MOV R0, #50H ;用R0作数据指针LOOP:MOV A, R4ADD A, R0MOV R4, AINC R0 ;指向下一个数据,为下一轮作准备CLR AADDC A, R3 ;扩展衬16位(加进位)MOV R3, ADJNZ R2, LOOP例 二路电压值测量输入如图所示,需要测量V1和V2的值,测量值分别存放在60H和61H两个单元中,用P1.0切换:P1
29、.0=1,测量V1P1.0=0,测量V2因为测量、转换和计算处理程序相同,可用循环方法使用同一段程序实现SETB P1.0MOV R0, #60HLOOP: A/D转换(用延时、查询或中断法)计算处理,把电压转换成温度值结果存放在Acc中MOV R0, AINC R0JBC P1.0, LOOP 多重循环程序例 50ms延时程序-两重循环12MHz的晶振,一个机器周期为1s,DJNZ指令周期为2s。DELAY:MOV R7, #200 ;1sDEL1:MOV R6, #123 ;1sNOP ;1sDEL2:DJNZ R6,DEL2 ;2sX123+2=248sDJNZ R7,DEL1 ;(24
30、8s2)X200+1=50001s; = 50.001MS例 搜索最大值从片内RAM的BLOCK单元开始存放一组无符号数,该数据块的长度存放在LEN单元中,查找出其中的最大数存放在MAX单元中。算法:先取出第一个数与第二个数进行比较,把大数放在Acc中,再用Acc中的大数与下一个数进行比较,同样把大数放在Acc中,直至比较结束,把最大数按要求存放起来。BLOCK: EQU 30HLEN: EQU 2FHMAX: EQU 2EHMOV R0, #BLOCK ;用R0作数据块地址指针MOV R7, LEN ;用R7作循环次数计数器DEC R7 ;循环次数数据块长度MOV A, R0 ;取第一个数L
31、OOP: INC R0 ;指向下一个数MOV 2DH, R0 ;取下一个数CJNE A,2AH,CHK ;两个数比较CHK: JNC LOOP1 ;无借位,Acc中数大,转判断是否比较完MOV A, R0 ;有借位,取大数到Acc中LOOP1: DJNZ R7, LOOP ;循环次数减,未比较完继续MOV MAX, A ;最后把最大数存入MAX单元 排序程序按从小到大的词序排列称作升序排列,反之就称为降序排列。数据排序的算法很多,如插入排序法,冒泡排序法,选择排序法等,这里以冒泡排序法为例加以说明。所谓冒泡排序法就是通过两两相邻的数相比较互换的方法,其过程很象气泡在水中上浮的现象,故称为冒泡法
32、。将一组8位无符号数升序排序。假设该数组的首址为FIRST,数组长度为n.SORT: MOV R0, # FIRST ;数据指针MOV R7, # n ;数组长度DEC R7 ;计数初值CLR F0 ;对换标志置0LOOP: MOV A, R0 ;取前数INC R0 ;指向后数CLR C ;MOV R2,A ;暂存前数SUBB A, R0 ;前数后数MOV A,R2 ;还原前数JC NEXT ;前数后数,不换XCH A,R0 ;前数后数,交换DEC R0 ;指向上一单元XCH A,R0 ;小数存上一单元INC R0 ;恢复指针SETB F0 ;置对换标志NEXT: DJNZ R7, LOOP
33、;未比较完继续JB F0, SORT ;有交换,继续RET ;无交换,返回或SORT: MOV R0, #FIRST ;数据指针MOV R7, #n ;数组长度DEC R7 ;计数初值CLR F0 ;对换标志置 0LOOP: MOV A, R0 ;取前数INC R0 ;指向后数MOV 2AH,R0 ;取后数CJNE A, 2AH,CHK ;前数后数CHK: JC NEXT ;前数后数,不换XCH A,R0 ;前数后数,交换DEC R0 ;指向上一单元XCH A,R0 ;小数存上一单元INC R0 ;恢复指针SETB F0 ;置对换标志NEXT: DJNZ R7, LOOP ;未比较完继续JB
34、F0, SORT ;有交换,继续RET ;无交换,返回 4.3.4 子程序的设计和调用 子程序概念在一个较长的程序中,如有若干多次重复出现的指令组,虽然可能其中有些操 作数或操作地址不同,可以把程序中经常使用的、重复的指令组设计成可供其他程 序使用的独立程序段,这样的程序段就称为子程序。使用这种子程序的程序就称为 主程序。要使用子程序需要解决4个问题: 主程序怎样调用子程序; 主程序怎样把必要的数据信息传送给子程序,子程序又如何回送信息 给主程序; 子程序中保护和恢复主程序现场问题; 子程序执行完后如何正确返回主程序。 子程序结构 必须具有标号首地址,即要给所编写的子程序起个名字; 必须要有入
35、口参数和出口参数(条件); 用堆栈操作(压栈)保护和(出栈)恢复现场; 子程序的结尾必须是一条返回主程序指令RET。 子程序的调用和返回 子程序独立于主程序之外,可供同一程序多次调用,也可供不同程序分别调用; 子程序调用专用指令LCALL和ACALL此指令将其后面一条指令的地址压入栈顶,保护断点,sp+2,指向新栈顶,接着把要调用的子程序首地址送入PC 子程序返回返回指令RET将主程序的断点从堆栈中送回PC(出栈),以保证正确返回主程序继续执行。例 编写程序计算c=a 2 b 2 ,设a、b、c分别存放在片内RAM的DAS、DBS、DCS单元中。这个问题可以用调用子程序来实现,即通过两次调用查
36、平方表子程序,再把结果相加。主程序:START: MOV A, DAS ;取第一个操作数aACALL SQR ;调用查表子程序MOV R1, A ;暂存a 2 MOV A, DBS ;取bACALL SQR ;调用查表子程序ADD A, R1 ;a2 +b2 cMOV DCS, A ;存放结果子程序:SQR: INC A ;偏移量调整,加RET一字节MOVC A,A+PCRETTAB: DB 0,1,4,9,16DB 25,36,49,64,81END 子程序嵌套主程序与子程序的概念是相对的。一个子程序可以多次被调用而不会被破坏,在子程序中也可以调用其他子程序,这就称为多重转子或子程序嵌套。
37、子程序库把一些常用的标准子程序驻留在ROM或外存中,构成子程序库供用户调用。丰富的子程序会给用户带来极大的方便,这就相当于积木,用这些积木模块可以组合成各种不同的程序,完成各种不同的功能。子程序越多,使用就越方便,编程就越省时间。在使用这些子程序时,只要用一条调用指令就行了。 子程序文件() 子程序名称和目的的简述() 子程序的入口条件和出口条件() 子程序占用寄存器和内存的情况() 子程序嵌套情况4.3.5 如何评价程序的优劣 可靠性在任何情况下程序都能正确运行,这样的程序才是可靠的。注意上机通过的程序不一定是可靠的。需要经过各种场合、时间的考验后才能知道可靠不可靠。 时空指标要求执行的时间短,速度快;占用的存储单元少。 可扩展性同样一个程序只要改变初值就能处理更多相同情况下的数据,尽量使之具有通用性。 便于使用阅读方便,容易理解,数据结构安排合理。 容错性允许使用者出错,即使操作有错误的情况下,也能保证正确的运行和得到正确的结果,并具有自检能力。 兼容性向上兼容和向后兼容