考试 子程序设计1
子程序设计
子程序设计在程序设计过程中,经常遇到在程序的不同位置需使用完全相同的一段程序的情况。
为了避免多次出现同一段程序,节省程序存储器空间,可将这段程序写成独立的程序段,在任何需要的地方都可调用这段程序,运行完这段程序后再返回原程序继续运行,这样的独立程序段就称为子程序,而调用子程序的程序称为主程序。
子程序的引入大大简化了程序结构,增加了程序的可读性,避免了重复性工作,缩短了整个程序。
子程序还增强了程序的可移植性。
一些常用的运算程序写成子程序形式,可以随时引用、参考。
调用子程序过程由调用指令完成,MCS-51单片机有二条调用指令:ACALL addr11和LCALL addrl6。
指令中的地址为子程序的入口地址,在汇编语言中通常用标号来代表。
在执行这二条指令时,单片机将当前的PC值压入堆栈。
子程序的最后是返回指令RET,这条指令将堆栈的内容传入PC中,保证程序返回调用的地方继续运行。
在子程序运行时,可能要改变一些寄存器或数据存储器的内容。
有时这些内容是主程序正确运行所必不可少的。
因此,在子程序调用时,先将这些内容保存起来,子程序返回前再恢复原来的内容、这一过程称为保护现场。
保护现场通常由堆栈来完成。
需要保护现场时。
在子程序开始时安排压栈指令,将需要保护的内容压入堆栈,在子程序的最后,则设置出栈指令,将这些内存弹出堆栈,送回原来的单元。
在子程序调用时,还有一个需要注意的问题,即参数传送问题。
在子程序调用时,主程序应先把有关参数放到某些约定的位置,子程序运行时,可以从约定位置得到这些参数。
同样,子程序结束前也应把运算结果送到约定位置,返回主程序后,主程序从约定位置上获得这些结果。
参数传递可以采用工作寄存器或累加器A、地址寄存器和堆栈等来完成。
在子程序执行过程中调用其它子程序,这种现象称为子程序嵌套。
MCS-5l单片机允许多重嵌套。
子程序的结构与一般程序没有什么差别,最重要的标志是在其最后有一条返回指令。
另外,在需要保护现场时,子程序的开始和结束都有入栈和出栈指令。
子程序设计
RET
SQR:ADD MOVC A,@A+PC
RET
TAB: DB DB 0,1,4,9,16 25,36,49,64,81
;返回
主讲:吴政江
第4章
汇编语言程序设计
从上例中,可以得出以下几点:
(1) 汇编语言子程序编写格式很简单,只需第一条 指令要有标号,最后一条指令是RET,其它可根据程 序功能编写即可。 (2) 调用子程序是通过指令ACALL(当然也可以使
第4章
汇编语言程序设计
主讲:吴政江
第4章
汇编语言程序设计
三、子程序在编写和调用时应注意以下几点: (一)、子程序结构独立 程序“一进一出”,即一个入口地址和一个返回地址。入口处必须有标号,子 程序调用指令通过标号对子程序进行调用。出口处必须是返回指令RET。 (二)、现场保护和现场恢复 主程序在运行过程中使用了一些寄存器,在子程序 中可能也要用到这些寄存器。为了避免对主程序还有用 PUSH Acc PUSH PSW
的内容被子程序覆盖掉,在执行子程序前必须设法保护
这些寄存器的内容,称为现场保护。在执行完子程序返 回主程序前,还要恢复这些寄存器的内容,称为现场恢 复。一般是通过堆栈操作指令或工作寄存器换区指令对 现场进行保护和恢复。如右边程序所示:
PUSH B ;保护现场
┇ POP B POP PSW POP Acc ;恢复现场 RET ;返回
用指令LCALL)实现的。
(3) 调用子程序时,计算机只自动保护和恢复断点地 址,其它寄存器和直接地址单元的内容则需编程人员
根据程序具体情况通过一些指令进行保护和处理。
主讲:吴政江
第4章
汇编语言程序设计
(4) 调用子程序时常常需要参数传递,即子程序从调 用程序中获取数据进行处理,并将处理完的数据结果 送回主程序,参数传递不能为立即数,应该采用存储 单元地址或寄存器。如上例中在调用子程序 SQR 时, 累加器A起着参数传递的作用。
第7章 子程序设计1
(4)段间间接调用
指令格式:CALL DWORD PTR dest ;dest为双 字存储单元操作数。 执行操作: ① (SP)← (SP)﹣2 ) ) ;修改堆栈指针 ② (SS:(SP))←(CS) ( ))← ) ;CS入栈 入栈 )) ③ (SP)←(SP)﹣2 ) ) ;修改堆栈指针 ))← ④ (SS:(SP))←(IP) ( )) ) ;IP入栈 入栈 ⑤ (IP)←dest的低地址值 ) 的低地址值 ⑥ (CS)←dest的高地址值 ) 的高地址值 该指令的执行与段间直接调用类似,区别是根据寻址 方式求出有效地址后,把指定存储单元的低字内容送 到IP寄存器,高字内容送到CS寄存器。
以上几条调用指令在使用时应注意:
① 宏汇编程序MASM能根据定义过程时所指定的过程 类型决定采用段内直接调用还是段间直接调用。如果 先调用后定义,为了调用远过程,必须在过程名前加 类型说明符“FAR PTR”,调用近过程可以在过程名前 加类型说明符“NEAR PTR”或省略。 ② 对于间接调用,如果操作数是16位操作数,则汇编 成段内间接调用;如果操作数是32位操作数,则汇编 成段间间接调用。如果发生调用指令语句在前,有关 变量定义伪指令在后的情况,则需要在调用语句中用 PTR等操作符加以说明。
例7-4:
下面两条指令均是段内间接调用。 CALL BX CALL WORD PTR [BX] 第一条指令的操作数为寄存器BX,即BX 的内容作为子程序的入口偏移地址。第 二条指令的操作数为字存储单元。寄存 器BX所指的一个字存储单元中的内容作 为子程序的入口偏移地址。
(3)段间直接调用
指令格式:CALL FAR PTR 过程名 执行操作: ① (SP)← (SP)﹣2 ) ) ;修改堆栈指针 ))← ② (SS:(SP))←(CS) ( )) ) ;CS入栈 入栈 ③ (SP)←(SP)﹣2 ) ) ;修改堆栈指针 ④ (SS:(SP))←(IP) ( ))← ) ;IP入栈 入栈 )) ⑤ (IP)←过程入口地址的偏移量 ) ⑥ (CS)←过程入口地址的段地址 ) 该指令执行时先把返回地址的段地址压入堆栈,再把返回 地址的偏移量压入堆栈,达到保存返回地址的目的。然后 把过程入口地址的段地址和偏移量分别送入CS和IP,达到 转移的目的。
C语言程序设计基础试题一及答案
C语⾔程序设计基础试题⼀及答案《程序设计基础》考试试卷⼀班级姓名学号____________⼀、选择题(20分)1.算法具有五个特性,以下选项中不属于算法特性的是(A)有穷性(B)简洁性(C)可⾏性(D)确定性2.以下选项中可作为C语⾔合法常量的是(A)-80. (B)-080 (C) (D)3.以下叙述中正确的是(A)⽤C语⾔实现的算法必须要有输⼊和输出操作(B)⽤C语⾔实现的算法可以没有输出但必须要有输⼊(C)⽤C程序实现的算法可以没有输⼊但必须要有输出(D)⽤C程序实现的算法可以既没有输⼊也没有输出4.以下不能定义为⽤户标识符是(A)Main (B) _0 (C) _int (D) sizeof5.以下选项中,不能作为合法常量的是(A) (B) (C)+4 (D)6.数字字符0的ASCII值为48,若有以下程序main(){char a='1',b='2';printf("%c,",b++);printf("%d\n",b-a);} 程序运⾏后的输出结果是(A)3,2 (B)50,2 (C)2,2 (D)2,507.有以下程序main(){int m=12,n=34;printf("%d%d",m++,++n); printf("%d%d\n",n++,++m);}程序运⾏后的输出结果是(A) (B) (C) (D)8.有以下语句:int b;char c[10];,则正确的输⼊语句是A)scanf("%d%s",&b,&c); B) scanf("%d%s",&b,c);(C)scanf("%d%s",b,c); D)scanf("%d%s",b,&c);9.有以下程序main(){int m,n,p;scanf("m=%dn=%dp=%d",&m,&n,&p);printf("%d%d%d\n",m,n,p); } 若想从键盘上输⼊数据,使变量M中的值为123,N中的值为456,P中的值为789,则正确的输⼊是A)m=123n=456p=789 B)m=123 n=456 p=789 C)m=123,n=456,p=789 D)123 456 78910.有以下程序main(){int a,b,d=25;a=d/10%9;b=a&&(-1);printf("%d,%d\n",a,b); }程序运⾏后的输出结果是A)6,1 B)2,1 C)6,0 D)2,011.有以下程序main(){int i=1,j=2,k=3;if(i++==1&&(++j==3||k++==3))printf("%d %d %d\n",i,j,k);}程序运⾏后的输出结果是(A)1 2 3 (B)2 3 4 (C)2 2 3 (D)2 3 312.若整型变量a、b、c、d中的值依次为:1、4、3、2。
子程序设计
第5章 子程序设计
5.1 子程序的设计方法 5.2 子程序的嵌套
5.1 子程序的设计方法
子程序又称为过程,相当于高级语 言中的过程和函数。在一个程序的不同 部分,往往要用到"类似"的程序段,即这 些程序段的功能和结构形式都相同,只 是某些变量赋值不同。此时就可以把这 些程序段写成子程序形式,以便需要时 调用它。
5.1 子程序的设计方法
如果调用程序和过程在同一个代码段中,则使用 NEAR属性。
5.1 子程序的设计方法
如果调用程序和过程不在同一个代码段中,则使用
FAR属性。
5.1 子程序的设计方法
上例中SUBT为一过程,它在两处被调用, 一处是与它在同一段的SEGX段内,另一处是在 另一段SEGY段内。为此,SUBT必须具有FAR 属性以适应SEGY段调用的需要。SUBT既然有 FAR属性,则不论在SEGX段或SEGY段,对 SUBT的调用就都具有FAR属性。
5.1 子程序的设计方法
(3) 通过地址表传送参数地址 这种方法是在主程序中建立一个地 址表,把要传送给子程序的参数都存放 在地址表中,然后把地址表的首地址通 过寄存器BX传送到子程序中去。子程序 通过地址表取得所需参数,并把结果存 入指定的存储单元中去。
汇编语言程序 掌握子程序的设计(2023版)
汇编语言程序掌握子程序的设计汇编语言程序设计——子程序的设计一、引言汇编语言是一种低级别程序设计语言,与计算机硬件之间的联系非常紧密。
掌握子程序的设计是汇编语言程序设计的重要环节之一,本文档将详细介绍汇编语言程序中子程序的设计方法。
二、子程序的概念⒈子程序的定义子程序是一段独立的代码段,用于完成特定的功能,可以被主程序或其他子程序调用。
⒉子程序的优点⑴提高程序的模块化和可读性⑵重复利用代码,减少代码冗余⑶便于程序的维护和调试三、子程序的设计⒈子程序的设计要素⑴子程序的输入参数⑵子程序的返回值⑶子程序的功能描述⒉子程序的设计步骤⑴确定子程序的功能和输入参数⑵设计子程序的算法⑶编写子程序的代码⑷调试子程序并验证其正确性四、子程序的调用与返回⒈子程序的调用⑴传递参数⑵调用子程序⑶获取返回值⒉子程序的返回⑴返回值的存储⑵返回地质的存储五、子程序的参数传递⒈参数传递的方式⑴寄存器传递参数⑵栈传递参数⑶内存传递参数⒉参数传递的注意事项⑴参数传递的顺序⑵参数传递的大小和类型⑶参数传递的规范六、子程序的返回值⒈返回值的存储方式⑴寄存器存储返回值⑵内存存储返回值⒉返回值的类型⑴整型返回值⑵实型返回值⑶字符串返回值七、附件本文档没有附件。
八、法律名词及注释⒈子程序:在计算机程序中,独立完成特定功能的代码段。
⒉模块化:将程序分成多个独立的模块,每个模块负责完成特定功能。
⒊可读性:指程序的易读程度,便于程序员理解和维护。
⒋代码冗余:程序中重复出现的代码。
⒌算法:解决问题的一系列步骤。
实验3(子程序设计)
SI,CX赋初值
取第一个数 存于BH、BL
INC SI 取数存于AL
是
BH:存放较大值 BL:存放较小值 AL:当前值 比较分以下三种情况: AL比BL小 AL比BH大 AL在BL、BH之间
AL<BL 否 否 AL>BH 是 BH←AL DEC CX 否 CX=0? 是 结束
BL←AL
(3)编程要点
Hale Waihona Puke 3、编程提示(1)数据要求
可在数据段内定义;也可从键盘接收任意字符。
(2)子程序设计
①子程序定义格式
子程序名 PROC … RET ;子程序返回 NEAR或FAR;NEAR可省略
子程序名 ENDP ②子程序调用 CALL 子程序名
3、编程提示
开始
(3)编程要点(重点)
• 如何找最大、最小数?
( 子程序流程图如右图所示)
找到后,如何显示?
•考虑以下情况:
①一位十进制,如0~9如何显示?(必须完成) (常用DOS功能调用中的2号功能调用,注意数字与ASCII值对应关系。) ②两位十六进制,如3EH,80H,12H…如何在屏幕上显示?(建议试做) (分高低位显示,请参考实验指导书P76。)
4.注意事项
(1)段内调用时,子程序所处的位置。
子程序设计2实验报告中必须有程序流程图3实验报告中必须有对程序调试的小结4实验报告中必须有源程序清单及注释
1、实验项目
设有10个无符号数的字节序列,利用子程序的方法编写 程序,找出其中的最大、最小值,并在屏幕上显示。
2、实验目的
(1)掌握子程序设计的基本方法,包括子程序的定义、 调用和返回。 (2)巩固常用DOS功能调用。
(2)数据变量定义格式。
汇编语言程序设计_第6章 子程序设计(参考答案)
第6章子程序设计本章要点:子程序的定义、调用和返回,寄存器的保护盒恢复,参数传递方法尤其是堆栈传递参数,模块化程序设计的基本方法,DOS功能调用。
一、单项选择题6.1.1 下列叙述不正确的是(A)。
A. 在子程序中的保护现场只能用堆栈来实现B. 在子程序中的保护现场用堆栈来实现是其中的一种方法C. 在子程序中的保护现场可以有多种实现方法D. 在子程序中的保护现场可以将要保护的内容送内存变量来实现6.1.2 下列叙述不正确的是(B)。
A. 在汇编语言程序中,每一个过程允许有多条RET指令B. 在汇编语言程序中,每一个过程只允许出现一条RET指令C. 在汇编语言程序中,每一个过程结束之前一定有一条RET指令D. 在汇编语言程序中,以过程形式表示的代码段一定有一条RET指令存在6.1.3 下列叙述正确的是(B)。
A. 执行一条段内返回指令,先从堆栈弹出两个字节的内容,然后SP-2。
B. 执行一条段内返回指令,先从堆栈弹出两个字节的内容,然后SP+2。
C. 执行一条段内返回指令,先从SP-2,然后从堆栈弹出两个字节的内容。
D. 执行一条段内返回指令,先从SP+2,然后从堆栈弹出两个字节的内容。
6.1.4 在进行DOS功能调用时,其功能号应先送(C)。
A. AL寄存器B. BL寄存器C.AH寄存器D. DH寄存器二、填空题6.2.1 在子程序的设计中,通常用堆栈来保护现场和恢复现场。
而堆栈的操作原则是__先进后出,或后进先出___。
6.2.2 如果主程序和子程序在同一代码段中,则主程序调用子程序时只改变__偏移__地址;如果主程序和子程序不在同一代码段中,则主程序调用子程序时要改变__段地址和偏移_____地址。
6.2.3 一个子程序调用另一个子程序称为___子程序嵌套____;一个子程序直接或间接调用该子程序本身称为___递归(调用)_。
6.2.4 以过程定义的子程序有两种类型的属性,它们分别是___NEAR_____和___FAR_______。
子程序设计和系统功能调用例题
例8.2.1试设计一程序,完成两个长补码的加法,其中两个长补码的长度是相同的,并且采用低地址存放低位,高地址存放高位的方式存储。
加法功能使用子程序实现,两个长补码的起始地址、长补码的长度(以字为单位)、运算结果的起始地址均由主程序以入口参数的形式传递给子程序;运算是否溢出使用一个字节标志来表示,00H表示运算无溢出,0FFH 表示运算溢出,子程序将此溢出标志以出口参数的形式传递给主程序。
本例中参数传递方式采用寄存器传递方式。
1)设计参数传递约定题目已指明参数传递为寄存器传递方式,这里只需要具体约定寄存器与参数间的对应关系。
在本例中,我们约定主程序通过SI、DI寄存器传递两个长补码的起始偏移量(认为两个长补码位于同一数据段,并且段基值保存到DS中),通过CX寄存器传递补码的长度,通过BX寄存器传递运算结果的起始偏移量(认为段基值已保存在DS中);并且,我们约定子程序通过DL寄存器传递溢出标志。
2)源程序设计参数传递约定设计完成后,我们开始源程序设计,主程序与子程序的相应代码如下所示。
DA TA SEGMENTV AR1 DW 5482H, 669EH, 02C7H, 14B2H, 0C254HV AR2 DW 8C2BH, 0C24CH, 0AB12H, 357AH, 41A5HLEN EQU $-V AR2SUM DW LEN DUP(0) ; 用于保存运算结果OVR DB ? ; 用于保存溢出标志DA TA ENDSSTACK1 SEGMENT STACK ; 子程序设计必须使用堆栈段DW 40H DUP(0)STACK1 ENDSCODE SEGMENTASSUME CS: CODE, DS: DA TA, SS: STACK1BEGIN: MOV AX, DA TAMOV DS, AXLEA SI, V AR1 ; 传递入口参数LEA DI, V AR2MOV CX, LENLEA BX, SUMCALL LONGADD ; 调用子程序MOV OVR, DL ; 保存出口参数MOV AH, 4CHINT 21HLONGADD PROCPUSHF ; FR、AX入栈,保护CPU现场PUSH AXCLC ; 清除CF标志,保证第一次执行ADC时等同于ADD L1: MOV AX, [SI]ADC AX, [DI] ; 完成当前字的加法,引入了上次加法的进位PUSHF ; 保护OF标志MOV [BX], AX ; 当前字的计算结果保存到指定位置ADD SI, 2 ; 修改SI、DI、BX,使它们指向下一个字ADD DI, 2ADD BX, 2POPF ; 恢复OF标志LOOP L1 ; 计数循环,完成所有字单元的加法后退出循环JO L2 ; 判断最后一次运算是否溢出MOV DL,0 ; 无溢出则将0送至DL保存,传递出口参数JMP L3L2: MOV DL,0FFH ; 有溢出则将0FFH送至DL保存,传递出口参数L3: POP AX ; 恢复CPU现场POPFRET ; 返回主程序LONGADD ENDPCODE ENDSEND BEGIN读者在上例中应注意,首先,主程序向子程序传递入口参数、取得出口参数都是按照约定来进行的;其次,读者应注意子程序中的现场保护与恢复,它们分别在子程序的首位部分用PUSH和POP指令来实现;第三,由于上例中采用寄存器来传递参数,当执行子程序时,各参数已在寄存器中就位,使我们在子程序中没有找到“取入口参数”的动作,但实际上入口参数在子程序中已经可以直接使用。
子程序设计
四、过程间的参数传递方式
主调程序在调用子程序时,经常需要传送一些参数给子程 序;子程序运行完后也经常要回送一些信息给调用程序:这 种主调程序和子程序之间的信息传送称为参数传送(或称过 程通信)。参数传送方式可以有以下几种:
1、通过寄存器传递数据 2、通过变量名传送数据 3、通过堆栈传送参数或参数地址 4、通过地址表传送参数地址
数。在一个程序的不同部分,往往用到相同或类似的程序 段,这些程序段的功能和结构形式都相同,只是某些变量 的赋值不同,此时就可以把这些程序段写成子程序形式, 以便需要时可以调用它。有些程序段对于某个用户可能只 用到一次,但它是一般用户经常用到的,如十进制数转换 成二进制数,二进制数转换为十进制数并显示输出等,对 于这些常用的特定功能的程序段也经常编制成子程序的形 式供用户使用。
第五节 子程序的设计及其使用
2.过程定义伪操作 过程定义伪操作用在过程(子程序)的前后,使整个过
程形成清晰的、具有特定功能的模块。其格式为: <过程名> PROC <属性> ┇ RET [n] <过程名> ENDP
其中过程名为标识符,它又是子程序入口的符号地址, 它的写法和标号的写法类同。属性是指类型属性,它可以 是NEAR或FAR。属性为NEAR的过程只能在本段(过程所在段) 内使用,而属性为FAR的过程则可以在其它段中使用。
• 假设在数据段中DA1定义有一字符串,现对每一个字符的 ASCII码统计‘1’的个数。统计的个数存放在DA2的数据 区内。
DATA SEGMENT DA1 DB ‘ABCDEFGHUKLMNOP’ CUNT EQU $-DA1 DA2 DB CUNT DUP(0)
DATA ENDS CODE SEGMENT
子程序设计
计
aldisp1:
CMP DL,39H JBE aldisp1 ADD DL,7 MOV AH,2 INT 21H
ALdisp
POP DX POP CX POP AX RET ENDP
;
联系P134 习题4.14 文件名 ZMT.ASM
2021/3/13
感谢演讲人:MFKSCGO
10
软件工程18、计算机18
Y 返回
AX(即n!)送BX M送CX
调用SUB1子程序 AX/BX(即m!/n!)送BX
m—n送CX 调用SUB1子程序 AX(即(m—n)!)送BX
AX/BX(即m!/n!/ (m—n)!)送AX
2021/3/13
感谢演讲人存:储MAFXKSCGO
11
结束
软件工程18、计算机18
子程序设计
DATA SEGMENT
言
.CODE
程
.STARTUP
序
CALL checksumb
设
.EXIT 0
计checksPuUmSbH
PROC AX
PUSH BX
PUSH CX
2021/3/13
感谢演讲人:MFKSCGO
20
语言.SMMTOOAVVRTBCUXXP,,;OcFo设FuSn置EtT入a口rr参ay数;;BC(XX←←含有数数D组组S←的的偏元数移素组地个的址数段地址)
程 CALL checksuma ;调用求和过程
校验和
序.MEOXVITre0sult,AL ;处理出口参数 设checksuma PROC
段间返回
CS ←(SP) SP ← SP+2
RET n 格式: RET n 功能:IP ←(SP) SP ← SP+2
子程序设计
在子程序调用时,主程序应先把有关参数放到某些约定的位置,子程序运行时,可以 从约定位置得到这些参数。
在子程序执行过程中调用其它子程序,这种现象称为子程序嵌套。MCS-5l单片机允许 多重嵌套。
子程序的结构与一般程序没有什么差别,最重要的标志是在其最后有一条返回指令 。另外,在需要保护现场时,子程序的开始和结束都有入栈和出栈指令。
以下例子主要是说明子程序的调用过程和参数传递的方法。
例1 单字节有符号数的加、减法程序。
解: 该程序的功能为(R2)± (R3)→R7,R2和R3中为有符号数的原码,R7中存放计算结果的原码 。运算结果溢出时OV置位。
程序为C.7
;符号位取反
MOV
R3, A
ADD1: MOV
A, R3
ACALL CMPT
;加数或减数求补
MOV
R3, A
MOV
A, R2
ACALL CMPT
;被加数或被减数求补
MOV
R7, A
OVER: RET
例2 4位BCD码的减法程序。 解: 由于BCD码调整指令在减法指令后面是不起作用的,因此不能用直接采
用BCD码调整指令来完成BCD码的减法运算。本例是BCD码减法运算的一种方 法。
设被减数放在50H和5lH单元中,减数放在60H和61H中,差放入40H和41中。 ;主程序
MOV R1, #50H MOV R0, #60H CLR C ACALL BSUB MOV 40H, A ACALL BUSB MOV 41H, A
为了避免多次出现同一段程序节省程序存储器空间可将这段程序写成独立的程序段在任何需要的地方都可调用这段程序运行完这段程序后再返回原程序继续运行这样的独立程序段就称为子程序而调用子程序的程序称为主程序
子程序设计——精选推荐
第7章:子程序设计1、主程序和所调用的子程序在同一代码段中,子程序的属性应定义为( C )。
DXA.TYPE B.WORD C.NEAR D.FAR2、 MOV AL,38HMOV BL,49HCALL SUBOINC ALDEC CL┇SUBO PROCADD AL,BLMOV CL,ALDAARETSUBO ENDP上述程序段运行后,AL=________88H _____________,CL=________80H __________。
CXFX3、FACT PROCPUSH DXMOV DX,AXCMP AX,0JZ DONEDEC AXCALL FACTMUL DXPOP DXRETDONE:MOV AX,1POP DXRETFACT ENDP若执行以上子程序前,(AX)=5,则子程序完成的功能是:求5!(或求5的阶乘) ,执行该子程序后(AX)= 120 。
CXFX4、在一段汇编程序中多次调用另一段程序,用宏指令比用子程序实现起来。
(占内存空间大,但速度快)。
DX5、设在DAT单元存放一个-9~+9的字节数据,在SQRTAB数据区中存放了0~9的平方值,请用直接查表法编写一个子程序,在SQRTAB中查找出DAT单元中数据对应的平方值送SQR单元。
并写出主程序的调用方式。
CX数据段如下:DATA SEGMENTDAT DB XXHSQRTAB DB 0,1,4,9, (81)SQR DB?DATA ENDS答:DATA SEGMENTDAT DB XXHSQRTAB DB 0,1,4,9,…,81SQR DB?DATA EMDSSTACL1 SEGMENT PARA STACKDW 20H DUP(?)STACK1 ENDSCODE SEGMENTASSUME CS:CODE,DS:DATA,SS:STACK1START: MOV AX,DATAMOV DS,AX┇CALL SUBROT┇MOV AH,4CHINT 21HSUBROT PROCPUSH AXPUSH BXLEA BX,SQRTABMOV AL,DATTEST AL,80HJNS NEXTNEG ALNEXT: XLAT SQRTABMOV SQR,ALPOP BXPOP AXRETSUBROT ENDPCODE ENDSEND SRART6、设在内存单元SQTAB首址开始存放了0~15的平方数表。
第4章 子程序设计.
AX
CSEG ASSUME ASC_BIN
7/23/2018 7:28 PM
RET
ENDP ENDS
6
寄存器参数传递
STACK SEGMENT DW 256 DUP (?)
TOP
STACK DATA
LABEL WORD
ENDS SEGMENT
ASC_STG
DB
4 DUP (?)
BIN_RESULT DW ? DATA ENDS
子程序设计
子程序又称为过程
1、过程的定义和调用 过程的定义 Procedure name PROC attribute … RET Procedure name ENDP 过程名(Procedure name)是标识符
1 7/23/2018 7:28 PM
子程序设计 1、过程的定义和调用 过程的调用 CALL指令
过程
PROADD PUSH PUSH PUSH PUSH PUSH MOV MOV MOV MOV XOR MOV NEXT: ADD JNC INC
7/23/2018 7:28 PM
PROC NEAR AX DX CX NO_CARRY: SI DI SI,[BX];取数组地址。 DI,[BX+2];取元素个数。 CX,[DI] DI,[BX+4];取和数地址。 AX,AX DX,AX AX,[SI] PROADD NO_CARRY DX
14 7/23/2018 7:28 PM
STACK CSEG
利用地址表传送参数
主程序
MOV MOV MOV MOV CALL MOV MOV MOV LEA CALL CSEG
TABLE,OFFSET ARY1 ;装填地址表。 TABLE[2],OFFSET COUNT1 TABLE[4],OFFSET SUM1 BX,OFFSET TABLE ;表地址存入BX。 NEAR PTR PROADD;求数组ARY1的和。 TABLE,OFFSET NUM;重新建立地址表。 TABLE[2],OFFSET N TABLE[4],OFFSET TOTAL BX,TABLE NEAR PTR PROADD;求数组NUM的和。 ENDS
子程序设计
实验九子程序设计一.实验目的1.掌握程序设计方法,合理划分层次2.掌握子程序的调用与返回的方法1.了解子程序的嵌套与递归二.实验内容与要求编制一程序,要求键入一个班的学生成绩,并存放于50字的ERADE数组中,然后根据ERADE中的成绩,把学生名次填入50字的RANK数组中,再按学号顺序把名次从终端上显示出来。
提示:1 程序MAIN功能:根据输入的学生成绩,计算并显示出学生名次。
2 程序INPUT功能:接收一个班级学生的成绩,各成绩之间用空格隔开。
3 程序RANKP功能:计算一个班级学生的名次。
(可参照循环程序(一)中的程序段)4 程序OUTPUT功能:输出(显示)一个班级的学生名次5 程序DECIBIN功能:十进制转换二进制,存入BX6 程序BINDEC功能:十进制转换二进制,并在屏幕上显示。
7 程序DEC_DIV功能:BX的内容除以CX的内容,并在屏幕上显示一位商。
一.程序框图:二.步骤1.自编主程序与子程序。
2.输入本班级某门基础课成绩。
三.思考题1.写出4位BCD码转二进制数的算法。
2.写出AX中进二制数转BCD码的算法。
3.将上述子程序结构改为模块化程序设计。
答案:DATA SEGMENTGRADE DW 10 DUP(?) COUNT EQU ($-GRADE) /2 ORG 20HRANK DW 10 DUP(1),'$' DATA ENDSSTACK SEGMENT STACKSTA DB 20 DUP (20H) TOP EQU $-STA STACK ENDSCODE SEGMENTASSUME CS:CODE,DS:DATA,SS:STACK START: MOV AX,DATAMOV DS,AXMOV AX,STACKMOV SS,AXMOV SP,TOPMOV DI,0BH ;成绩的个数XOR AX,AXXOR BX,BXINPUT: MOV AH,1 ;输入学生成绩INT 21HCMP AL,0DHJZ TRANAND AL,0FHMOV CL,4SHL AL,CLMOV DL,ALMOV AH,1INT 21HCMP AL,0DHJZ TRANAND AL,0FHADD AL,DLMOV GRADE[BX],AXADD BX,2MOV DL,20HMOV AH,2INT 21HJMP INPUTTRAN: XOR BX,BXMOV DL,0AH ;换行MOV AH,2INT 21HJMP LOOP1LOOP1: MOV AX,GRADE[BX] MOV CX,COUNTLEA SI,GRADE ;成绩的存放地址NEXT: CMP AX,[SI]JNC NO_COUNTINC WORD PTR RANK[BX] ;存放学生名次NO_COUNT: ADD SI,2LOOP NEXTMOV AX,RANK[BX] ; 输出学生名次CMP AL,0AHJB ASC1MOV DL,1ADD DL,30HMOV AH,2INT 21HMOV DL,0ADD DL,30HMOV AH,2INT 21HMOV DL,20HMOV AH,2INT 21HJMP ASC2ASC1: MOV DL,ALADD DL,30HMOV AH,2INT 21HMOV DL,20HMOV AH,2INT 21HMOV DL,20HMOV AH,2INT 21HASC2: ADD BX,2 ;对下一个学生排名DEC DIMOV CX,DILOOP LOOP1MOV AX,4C00HINT 21HCODE ENDS END START。
子程序设计
R0, SP R0 R0 A, @R0 A, # 0FH A, #2 A, @A+PC A, @R0
;取被转换数据 ;保留低半字节 ;修改A ;查表 ;结果送回堆栈
30H,31H,32H,…
【例4-17】求两个无符号数据块中的最大值。数据 块的首地址分别为60H和70H,每个数据块的第一个字 节都存放数据块的长度,结果存人5FH单元。
解 本例可采用分别求出两个数据块的最大值,然 后比较其大小的方法,求最大值的过程可采用子程序。
子程序名称:QMAX。
子程序入口条件:R1中存有数据块首地址。出口 条件:最大值在A中,
下面分别编写主程序和子程序。
主程序:
ORG
MOV
MOV
ACALL
MOV
MOV
ACALL
CJNE
NEXT: JNC
MOV
子程序:
ORG QMAX :MOV
MOV CLR LP1: INC CLR SUBB JNC
LP3: LP4:
MOV SJMP ADD DJNZ
RET
2200H A,@R1 R2,A A R1 C A,@R1 LP3
A,@R1 LP4 A,@R1 R2,LP1
;取数据块长度 ;R2做计数器 ;A清零,准备做比较 ;指向下一个数据地址 ;0+cY,准备做减法 ;用减法做比较 ;若A大,则转LP3
;A小,则将大数送A中 ;五条件转LP4 ;恢复A中值 ;计数器减1,不为零,转继续比较
;比较完,子程序返回
单片机原理及应用
假设一个字节的十六进制数在内部数据存储器40H单元, 结果存于41H、42H单元中,用堆栈进行参数传递。
MAIN: MOV SP,#55H
子程序设计实验报告1
子程序设计实验报告学号:0740303104姓名:雷凤子程序设计实验报告一、实验目的:1、训练子程序;调用程序以及DOS功能调用程序的编制,进一步熟悉和灵活使用系统功能调用,培养根据具体情况合理划分程序模块的能力2、掌握主、子程序之间的调用关系,联结方法,提高使用各种参数传递方法的正确性和灵活性。
3、掌握调试主、子程序的基本方法,通过调试进一步理解和加深堆栈在子程序设计中的重要意义的认识4、上机前要求写好被调试程序的程序文本,并进行静态调试,然后拟定好调试计划和上机操作步骤。
二、实验要求:1、具体了解和掌握call指令,主,子程序之间的调用和在使用时应注意的问题2、学习子程序设计和调用的一般方法。
三、实验内容1、实验任务试编制一程序,分别对NUM字节单元数组中统计出有多少个20,有多少个5,有多少个2,有多少个1.统计的个数分别放在NUM20、num5、num2、num1单元中。
1. 程序要求用主程序-子程序的结构形式编制。
2. 并且传递参数的方式为堆栈方法。
2、实验的原理在主程序部分,将统计个数的单元分别放在俩个通用寄存器——AH,AL,DH,DL中,数组首址和数组长度都压栈,设置一个循环次数,送给CX,再调用输出语句进行输出。
最重要的是子程序JUSUAN,做好保护现场等准备工作后就将数组中的每个元素分别与20,5,2,1比较,根据不同的结果转到不同的分支语句,对应的不同的计数器相应地增1,并修改地址,继续循环比较。
3、程序设计流程图子程序流程图四、实验步骤1、编辑(纪事本)DATAS SEGMENTNUM DB 20,1,20,5,2,5,2,2,2,20 COUNT EQU $-NUMNUM20 DB?NUM5 DB?NUM2 DB?NUM1 DB?;此处输入数据段代码DATAS ENDSSTACK SEGMENT PARA STACK 'STACK' STAPN DB 100 DUP(?);此处输入堆栈段代码STACK ENDSCODES SEGMENTASSUME CS:CODES,DS:DATAS,SS:STACK MAIN PROC FARPUSH DSSUB AX,AXPUSH AXMOV AX,DATASMOV DS,AXMOV AX,STACKMOV SS,AXSTART:MOV BX,OFFSET NUM ;取偏移地址MOV CX,COUNT ;数组长度送给CXPUSH BX ;数组首地址入栈PUSH CX ;数组长度进栈 CALL JISUAN ;调用子程序MOV NUM20,AH ;将统计的个数保存MOV NUM5,ALMOV NUM2,DHMOV NUM1,DLMOV CX,4 ;设置循环次数LEA DI,NUM20 ;取偏移地址COUT:ADD [DI],30H ;输出MOV DL,[DI]MOV AH,02HINT 21HINC DILOOP COUTRETMAIN ENDPJISUAN PROC;PUSH Bx ;保护现场PUSH CXPUSH BPMOV BP,SP ;当前栈顶地址送BP BEGIN:MOV DI,[BP+10] ;DIMOV CX,10 ;CXSUB AX,AX ;计数器清零SUB DX,DX ;计数器清零GO:CMP BYTE PTR [DI],20JE NEXT1 ;比较,相等就转CMP BYTE PTR [DI],5JE NEXT2CMP BYTE PTR [DI],2JE NEXT3CMP BYTE PTR [DI],1JE NEXT4DO: INC DI ;修改地址LOOP GOJMP ANEXT1: INC AH ;计数器加1 JMP DONEXT2: INC ALJMP DONEXT3: INC DHJMP DONEXT4: INC DL JMP DOA: ;POP BX ;恢复现场POP CXPOP BPRET 4;此处输入代码段代码;JISUAN ENDPCODES ENDSEND MAIN2、汇编(masm/ML)3、连接(link)4、调试(debug)5、运行3241Press any key to continue五、实验中各个步骤遇到的问题及解决方法、1、汇编(masm/ML)虽然思路比较清晰,但在用堆栈方式进行参数传递时出现了一些语法错误,不知道该何时进栈,对到底应该哪个寄存器进栈也没弄太明白。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
考试子程序设计
参见:/question/127711340.html
1、实验目的
掌握CALL指令的使用方法。
掌握子程序设计、编写、调试和运行的方法。
2、实验内容
(1)显示学生名次表
要求:接收从键盘输入的—个班的学生成绩,并存放于50字的grade数组中,其中grade+i保存学号为i+1的学生的成绩。
然后根据grade中的学生成绩,把学生名次填人50字的rank数组中,其中rank+i的内容是学号为i+1学生的名次。
再按学号顺序把名次从终端上显示出来。
分析:子程序划分的层次图如附图7所示。
可以看出,其中main为主控模块,其下—
层的三个模块为程序的三大部分。
现将各模块说
明表示如下:
1) 模块名:main为总控模块
输入:从键盘输入—个班的学生成绩。
输出:显示—个班的学生名次。
功能:根据输入的学生成绩,计算并显示学
生名次。
算法如下:
—个学生的名次等于成绩高于该生的学生
人数加1。
2) 模块名:input
输入:以学号为序从键盘输入—个班的学生成绩。
各个成绩之间用逗号隔开,最后以‘回车’符结束。
输出:把—个班的学生成绩存人grade数组。
功能:接收—个班的学生成绩。
调用子模块decibin把从键盘输入的—个十进制数转换为二进制数。
调用子模块crlf完成回车、换行功能。
3) 模块名:rankp
输入:从grade数组取得—个班的学生成绩。
输出:以学号为序计算出该班每个学生的名次存人rank数组。
功能:计算—个班的学生名次。
算法为:—个学生的名次等于成绩高于该生的学生人数加1。
4) 模块名:output
输入:从rank数组取得—个班的学生名次。
输出:把—个班的学生名次以学号为序在终端上显示出来。
功能:显示—个班的学生名次。
调用子模块binidec,以便把rank数组中的二进制数转换为十进制数并在终端上显示出来。
调用于模块crlf完成回车、换行功能。
5) 模块名:decibin;
输入:从键盘取得—个十进制数。
”
输出:把该数转换为二进制数并存人BX寄存器中。
功能:把从键盘取得的—个十进制数转换为二进制数,并将该数存入BX寄存器中。
6) 模块名:crlf
输出:向终端发出回车、换行符。
功能:完成—次回车、换行操作。
7) 模块名:binidec
输入:从BX寄存器取得—个二进制数。
输出:在终端屏幕上显示—个十进制数。
功能:把BX寄存器中的二进制数转换为十进制数,并在终端屏幕上显示出来。
调用子模块dec_div用来作除法运算并显示字符。
8) 模块名:dec_div
输入:从BX寄存器中取得需转换为十进制的数。
输出:在屏幕上显示—位十进制数。
功能:把BX寄存器中的二进制数除以相应的十的幂,并在屏幕上显示—位商,余数保存在BX寄存器中。
有了以上的层次图及模块说明,对程序的全貌就有了基本了解。
在附图8中,我们给出了除rankp以外的其余各子程序的程序流程图。
数据段可定义如下:
DATAREA SEGMENT
GRADE DW 50 DUP (?)
RANK DW 50 DUP (?)
COUNT DW 7
MESS1 DB ‘Grade?$’
MESS2 DB 13,10,‘Input Error!’,13,10,‘$’
MESS3 DB ‘Rank:$’
DATAREA ENDS
子程序RANKP可参考如下程序RANKP PROC NEAR
MOV DI,COUNT
MOV BX,0
LOOPl:MOV AX,GRADE[BX]
MOV WORD PTR RANK[BX],0
MOV CX,COUNT
LEA SI,GRADE
NEXT:CMPAX,[SI]
JG NO_COUNT
INCWORD PTR RANK[BX]
NO_COUNT:ADDSI,2
LOOP NEXT
ADD BX,2
DEC DI
JNE LOOPl
RET
RANKP ENDP
子程序BINIDEC可参考如下程序BINIDEC PROC NEAR
PUSH BX
PUSH CX
PUSH SI
PUSH DI
MOV CX,100D
CALL DEC_DIV
MOV CX,10D
CALL DEC_DIV
MOV CX,1D
CALL DEC_DIV
POP DI
POP SI
POP CX
POP BX
RET
BINIDEC ENDP
DEC_DIV PROC NEAR
……….
DEC_DIV ENDP
3、实验步骤
完善程序后按步骤进行操作。