实验4 子程序实验
子程序实验报告

一、实验目的1. 理解子程序的概念和作用。
2. 掌握子程序的编写方法和调用方式。
3. 学会使用子程序实现模块化编程,提高程序的可读性和可维护性。
二、实验环境1. 操作系统:Windows 102. 编译器:Visual Studio 20193. 编程语言:C++三、实验内容1. 子程序的定义与调用2. 子程序的参数传递3. 子程序的递归调用4. 子程序的应用实例四、实验步骤1. 子程序的定义与调用(1)编写一个简单的子程序,实现两个整数的加法运算。
```cpp#include <iostream>using namespace std;// 定义子程序int add(int a, int b) {return a + b;}int main() {int a = 10;int b = 20;int sum = add(a, b); // 调用子程序cout << "The sum of " << a << " and " << b << " is " << sum << endl; return 0;}```(2)编译并运行程序,观察输出结果。
2. 子程序的参数传递(1)编写一个子程序,实现两个整数的交换。
```cpp#include <iostream>using namespace std;// 定义子程序void swap(int &a, int &b) {int temp = a;a = b;b = temp;}int main() {int a = 10;int b = 20;cout << "Before swap: a = " << a << ", b = " << b << endl;swap(a, b); // 调用子程序cout << "After swap: a = " << a << ", b = " << b << endl;return 0;}```(2)编译并运行程序,观察输出结果。
子程序设计实验报告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)虽然思路比较清晰,但在用堆栈方式进行参数传递时出现了一些语法错误,不知道该何时进栈,对到底应该哪个寄存器进栈也没弄太明白。
实验一DEBUG的使用

实验一 DEBUG 的使用实验目的:1.学习使用.学习使用DEBUG DEBUG DEBUG程序的各种命令。
程序的各种命令。
程序的各种命令。
2.掌握.掌握8088/868088/868088/86指令系统指令系统指令系统---------算数指令。
算数指令。
算数指令。
3.掌握用.掌握用DEBUG DEBUG DEBUG调试自编程序的方法。
调试自编程序的方法。
调试自编程序的方法。
4.掌握.掌握8088/8086 CPU 8088/8086 CPU 寄存器的用途和存储器组织及它们之间的关系。
寄存器的用途和存储器组织及它们之间的关系。
寄存器的用途和存储器组织及它们之间的关系。
5.掌握内存操作数及寻址方法。
.掌握内存操作数及寻址方法。
6.掌握汇编语言伪操作.掌握汇编语言伪操作:BYTE PTR,WORD PTR :BYTE PTR,WORD PTR。
内容及步骤:一、一、DEBUG DEBUG 命令使用命令使用: :1、 敲 DEBUG 进入进入进入 DEBUG DEBUG 环境,显示提示符环境,显示提示符环境,显示提示符 '_ ' '_ '。
2、 用命令用命令 D100 10F D100 10F 观察内存中的观察内存中的161616进制码及屏幕右边的进制码及屏幕右边的进制码及屏幕右边的ASCII ASCII ASCII字符。
字符。
字符。
3、 用命令用命令 E100 30 31 32 E100 30 31 32 ………… 3F 3F 将30H 30H~~3FH 3FH写入地址为写入地址为写入地址为100H 100H 100H开始的内存单元中,开始的内存单元中,再用再用D D 命令观察结果,看键入的命令观察结果,看键入的161616进制数是什么字符的进制数是什么字符的进制数是什么字符的ASCII ASCII ASCII码码?4、 用命令用命令 F100 10F 'A' F100 10F 'A' 将'A''A'的的ASCII ASCII码填入内存,用码填入内存,用码填入内存,用D D 命令查看结果。
子程序设计实验报告范文精简处理

子程序设计实验报告范文精简处理实验报告是对实验目的、流程、结果和结论等内容的详细描述和总结。
以下是一份精简处理的子程序设计实验报告范文,共计1245字。
#实验报告名称:子程序设计实验##一、实验目的1.熟悉子程序的定义和使用方法;2.掌握子程序设计的基本思路和技巧;3.实践并提高对程序模块化设计的理解和能力。
##二、实验设备和材料-计算机-C语言编程环境##三、实验方法与流程1.根据实验要求,在C语言编程环境中编写一个独立的子程序;2.使用该子程序计算并输出指定的结果;3.程序编写完成后,编译并运行该程序,观察结果是否符合要求。
##四、实验内容1. 设计一个名为`sum`的子程序,接受一个整型数组和数组长度作为参数,计算数组元素之和,并返回该和;2.编写主程序,使用该子程序求解一个整型数组的元素之和;3.输出求和结果,观察是否正确。
##五、实验结果与分析实验中,我们使用了一组测试数据进行验证。
首先,定义一个整型数组`arr`,其中包含5个元素:{1, 2, 3, 4, 5}。
然后,将该数组和数组长度传递给`sum`子程序进行求和操作。
经过运行,我们得到的结果是15,与我们预期的结果一致。
因此,可以判断子程序设计正确,并成功实现了数组元素之和的计算功能。
##六、实验总结通过本次实验,我们成功设计并实现了一个独立的子程序,在主程序中调用该子程序计算了一个整型数组的元素之和。
通过此次实验,我们进一步熟悉了子程序的定义和使用方法,掌握了子程序设计的基本思路和技巧,并提高了对程序模块化设计的理解和能力。
这对于今后的软件开发和编程工作具有重要意义。
##七、实验心得本次实验让我更加深入地理解了子程序设计的重要性和作用。
通过将功能模块化,我们可以方便地组织和管理程序代码,提高代码的复用性和可维护性。
在实际的软件开发中,子程序设计及其正确使用是非常关键的,能够大大提高开发效率和代码的可靠性。
因此,我会继续学习和掌握更多的子程序设计技巧,并应用于未来的编程工作中。
实验五 子程序设计实验(设计性实验)

实验五子程序设计实验(设计性实验)一、实验要求和目的1.熟悉汇编语言程序设计结构;2.熟悉汇编语言子程序设计方法;3.熟悉利用汇编语言子程序参数传递方法;4.熟悉汇编语言字符串处理基本指令的使用方法;5.掌握利用汇编语言实现字符串的输入输出程序设计方法;6.掌握数制转换程序实现方法。
二、软硬件环境1、硬件环境:计算机系统 windows;2、软件环境:装有MASM、DEBUG、LINK、等应用程序。
三、实验涉及的主要知识子程序知识要点:1、掌握子程序的定义语句;过程名 PROC [near/far]过程体RET过程名 ENDP2.子程序结构形式一个完整的子程序一般应包含下列内容:1. )子程序的说明部分在设计了程序时,要建立子程序的文档说明,使用户能清楚此子程序的功能和调用方法。
说明时,应含如下内容:.子程序名:命名时要名中见意..子程序的功能:说明子程序完成的任务;.子程序入口参数:说明子程序运行所需参数及存放位置;.子程序出口参数:说明子程序运行结果的参数及存放位置;.子程序所占用的寄存器和工作单元;.子程序调用示例;2、)掌握子程序的调用与返回在汇编语言中,子程序的调用用CALL,返回用RET 指令来完成。
.段内调用与返回:调用子程序指令与子程序同在一个段内。
因此只修改IP;.段间调用与返回:调用子程序与子程序分别在不同的段,因此在返回时,需同时修改CS:IP。
3.)子程序的现场保护与恢复保护现场:在子程序设计时,CPU 内部寄存器内容的保护和恢复。
一般利用堆栈实现现场保护和恢复的格式:过程名PROC [NEAR/FAR]PUSH AXPUSH BXPUSH DX……POP DXPOP BXPOP AXRET过程名 ENDP4.子程序的参数传递方法1.寄存器传递参数这种方式是最基本的参数传递方式。
2.存储器单元传(变量)递参数这种方法是在主程序调用子程序前,将入口参数存放到约定的存储单元中;子程序运行时到约定存储位置读取参数;子程序执行结束后将结果也放在约定存储单元中。
子程序设计实验报告

子程序设计实验报告子程序设计实验报告1. 实验背景子程序是一种可重复使用的程序代码片段,能够被主程序调用执行。
本次实验旨在通过编写子程序来加深对子程序设计的理解,并能够熟练使用子程序进行程序的模块化设计。
2. 实验目的通过本次实验,我将掌握以下技能:- 理解子程序的概念和作用- 掌握子程序的定义和调用- 理解子程序的参数传递方式- 学会使用子程序进行程序的模块化设计3. 实验内容本次实验涉及三个任务,分别是:1. 编写一个计算两个数之和的子程序2. 编写一个计算阶乘的子程序3. 编写一个计算圆形面积的子程序4. 实验步骤4.1 编写计算两个数之和的子程序首先,我们需要编写一个子程序用来计算两个数之和。
以下是该子程序的代码示例:pythondef add_numbers(num1, num2):sum = num1 + num2return sum上述代码中,我们定义了一个名为`add_numbers`的子程序,该程序接收两个参数`num1`和`num2`,计算它们的和并返回结果。
4.2 编写计算阶乘的子程序接下来,我们需要编写一个子程序用来计算一个数的阶乘。
以下是该子程序的代码示例:pythondef factorial(n):if n <= 1:return 1else:return n factorial(n-1)上述代码中,我们定义了一个名为`factorial`的子程序,该程序接收一个参数`n`,计算`n`的阶乘并返回结果。
我们使用递归的方式实现了阶乘的计算。
4.3 编写计算圆形面积的子程序最后,我们需要编写一个子程序用来计算圆形的面积。
以下是该子程序的代码示例:pythondef calculate_circle_area(radius):pi = 3.14159area = pi radius radiusreturn area上述代码中,我们定义了一个名为`calculate_circle_area`的子程序,该程序接收一个参数`radius`,计算圆形的面积并返回结果。
子程序设计实验报告
子程序设计实验报告子程序设计实验报告1. 实验目的本实验旨在让学生通过设计和实现子程序,深入了解子程序的概念、使用方法和设计原则,培养学生的程序设计思维和编程能力。
2. 实验背景子程序是一个独立于主程序的独立程序段,它可以完成特定的任务并返回结果。
子程序可以被主程序调用多次,不仅可以提高程序的可读性和可维护性,还可以节省重复代码的编写和修改时间。
在实际的程序设计中,子程序被广泛应用于各种领域,如算法实现、功能模块划分、错误处理等。
3. 实验内容在这个实验中,我们将设计一个简单的子程序,实现一个猜数字的游戏。
游戏的规则是计算机随机一个1到100之间的整数,用户通过输入猜测的数字,计算机根据用户的猜测给出相应的提示,直到用户猜中为止。
实验要求:- 使用 Python 编程语言实现。
- 设计一个子程序,用于随机数。
- 设计一个子程序,用于接受用户输入并判断是否猜中。
- 设计一个子程序,用于给出猜测结果的提示。
4. 实验步骤4.1 设计子程序:随机数,我们需要设计一个子程序,用于一个1到100之间的整数。
可以使用 Python 的 random 模块中的 randint 函数来实现。
pythonimport randomdef generate_random_number():return random.randint(1, 100)4.2 设计子程序:接受用户输入并判断是否猜中接下来,我们设计一个子程序,用于接受用户输入的猜测数字,并判断是否猜中。
可以使用 Python 的 input 函数来接受用户输入,并使用 if 语句来判断用户猜测的数字是否与的随机数一致。
pythondef get_user_guess():guess = int(input(\。
实验的四子程序设计
实验四子程序设计一.实验目的:1.进一步掌握子程序设计方法;2.进一步掌握基本的DOS 功能调用.二.实验内容:1.从键盘上输入某班学生的某科目成绩.输入按学生的学号由小到大的顺序输入.2.统计检查每个学生的名次.3.将统计结果在屏幕上显示.4.为便于观察,输入学生数目不宜太多,以不超过一屏为宜.输出应便于阅读.尽可能考虑美观.5.输入要有检错手段.三、创新功能:1、监测不合法输入,当输入字符不为数字时,报错'Input illegal!'。
且允许用户从将当前错误数据重新输入,不必整体重新输入。
2、根据实际情况按百分制换算,当输入为3位数时自动结束读取,且最高分可限定为100分,例如输入999,排名时按照100分计算。
3、允许相同成绩的同学存在,不会影响排名。
4、允许输入的学生数任意,只要不超过堆栈空间均可。
5、输入输出界面友好,用户可以直观地看到名次表,对应学生学号和成绩。
6、利用堆栈空间,存储结构优越7、程序采用模块化设计,将实现相同功能的代码聚为宏块或子函数四.预习题:1.如何确定一个学生在这门科目中的名次?答:对成绩降序排序,同时记录学号2.你觉得输入结束后,采用什么方法进行比较以得到学生的名次最为简单?答:每次查找出当前最小成绩和其所对应学号入栈,这样形成的栈栈顶为最高分,弹栈时可依次降序输出成绩和对应学号,即为名次表。
3.准备好模块层次图.答:见下面流程图4.给出输出显示的形式.按顺序输入12个学生成绩:100、67、88、89、93、50、6、21、77、77、56、95,按ctrl+z 输入结束运行结果为:五、代码分析CHG MACRO X;将数字转换成ASCII码的宏块PUSH AXPUSH BXMOV AX,XMOV BL,10DIV BLADD AL,'0'ADD AH,'0'MOV BH,ALMOV BL,AHMOV X,BXPOP BXPOP AXENDMPRESENT MACRO X;显示单个字符的宏块MOV AH,02HMOV DL,XINT 21HENDMSTR MACRO STRING;显示字符串宏块MOV AH,09HMOV DX,SEG STRINGMOV DS,DXLEA DX,STRINGINT 21HENDMINPUT MACRO;输入单个字符宏块MOV AH,01HINT 21HENDMDATA SEGMENTBUFF DB 100 DUP(0);存入输入数据STRING1 DB 0DH,'Input illegal!','$' STRING2 DB 'score of stu ','$'STRING3 DB '100','$'STRING4 DB 'NO.','$'STRING5 DB 'The final rank is:','$' STRING6 DB ' STU:','$'STRING7 DB ' SCORE:','$'NUM DW 1;存入学生人数NUM2 DW 1P DW 1COUNT DB 0;计数成绩位数COUNT1 DW 1DATA ENDSSTACK SEGMENT 'STACK'DB 300 DUP(?)STACK ENDSCODE SEGMENTASSUME DS:DATA,CS:CODE,SS:STACK START: MOV DX,SEG DATAMOV DS,DXLEA SI,BUFF;输入模块LOOP1: MOV BH,'0'MOV BL,'0'STR STRING2MOV CX,NUM;移入CX进行转换显示CHG CX;将当前学号变为ASCIIPRESENT CHPRESENT CLPRESENT ':'L3: INPUTCMP AL,26;输入是否结束JZ EXICMP AL,0DHJNZ L1L2: INC NUM;输入结束CMP COUNT,1JZ Y1MOV [SI],BH;存成绩!!!!!!!!!MOV [SI+1],BLJMP Y2Y1: MOV BYTE PTR [SI],'0';当输入为一位数时,高位写0 MOV [SI+1],BHY2: INC SIINC SIMOV COUNT,0;计数变量清零PRESENT 0DHPRESENT 0AHJMP LOOP1L1: CALL JUDGECMP DL,0JNZ LOOP1;不合法重新输入INC COUNT;合法代表已经输入了一位数CMP COUNT,1JNZ CNT2MOV BH,AL;输入第一位数JMP L3CNT2: CMP COUNT,2;输入第二位数JNZ CNT3MOV BL,ALJMP L3CNT3: MOV BH,40HMOV BL,40HJMP L2;输入三位数代表当前输入结束;排序模块EXI: DEC NUMMOV AX,NUMMOV NUM2,AX;存起来NUM输入的个数LEA SI,BUFFMOV BH,40H;最小数MOV BL,40HMOV DX,NUM;待比较的数的个数LOOP2: CMP NUM,0JZ WALILOOP3: MOV CL,[SI];当前待比较单元送人SICMP CL,'!';是否为空单元JZ PLUSS;是则判断下一个CMP CL,BH;判断高位JA PLUSS;大于最小数,跳转判断下一个JB IMOV CL,[SI+1];判断低位CMP CL,BLJA PLUSS;大于最小数,跳转判断下一个I: MOV BH,[SI];更新最小值MOV BL,[SI+1]MOV DI,SI;存最小值的指针PLUSS: INC SI;判断下一个数INC SIDEC DX;还剩DX个数需要比较CMP DX,0JNZ LOOP3PUSH BX;跳出循环一轮比较完毕LEA SI,BUFF;SI重新指向待比较的数组首位PUSH CXMOV CX,DISUB DI,SI;记录最小值是第几个学生MOV AX,DI;存下二者差值MOV BL,2DIV BL;得到实际的学号偏移MOV DI,CXPOP CXMOV P,AXINC PCHG P;将学号转换为ASCII码入栈PUSH P;学号入栈MOV BYTE PTR [DI],'!';入栈后相应位置置入特殊符号,下次读取到此符号可不进行判断MOV BYTE PTR [DI+1],'!'DEC NUM;待入栈的变量-1MOV DX,NUM2MOV BH,40H;保证每次寻找最小值前BH、BL中内容为最大值MOV BL,40HJMP LOOP2;显示模块WALI: PRESENT 0DHSTR STRING5PRESENT 0DHPRESENT 0AHAGAIN: MOV CX,NUM2CMP CX,0;是否栈空JNZ GOONENDD: MOV AX,4C00HINT 21HGOON: STR STRING4MOV CX,COUNT1CHG CXPRESENT CHPRESENT CLPRESENT ':'POP CX;学号弹栈STR STRING6PRESENT CH;输出学号PRESENT CLPRESENT 20HSTR STRING6POP CX;成绩弹栈STR STRING7CMP CH,40H;是否是满分JZ NEAR PTR FULPRESENT CH;非满分显示分数的高低位PRESENT CLLINE: PRESENT 0DHPRESENT 0AHDEC NUM2INC COUNT1JMP AGAINFUL: PRESENT '1';满分直接显示100PRESENT '0'PRESENT '0'JMP LINEJUDGE PROC;判断输入是否合法,合法则DL=0不合法修改DL=1且输出字符串提示MOV DL,0CMP AL,'0'JNB NEXT1W1: STR STRING1MOV DL,1JMP OVNEXT1: CMP AL,'9'JA W1OV: RETJUDGE ENDPCODE ENDSEND START23、输出模块流程图:七、程序设计思路与总结本实验主要联系了宏块和子程序调用,属于排序问题。
子程序设计实验报告简版修正
子程序设计实验报告1. 实验目的本实验旨在通过设计子程序,巩固和提升学生对于子程序设计的理解和运用能力,培养学生的逻辑思维和程序设计能力。
2. 实验内容2.1 设计一个子程序,实现两个数相加的功能。
2.2 设计一个子程序,实现两个数相乘的功能。
2.3 设计一个子程序,实现对一个数的平方根的计算。
3. 实验步骤3.1 子程序1:实现两个数相加assemblyadd_numbers:; 输入:寄存器R1和R2分别存放两个待相加的数; 输出:寄存器R0存放相加结果; 保存现场PUSH R1PUSH R2; 执行相加操作ADD R0, R1, R2; 恢复现场POP R0POP R2POP R1; 返回RET3.2 子程序2:实现两个数相乘assemblymultiply_numbers:; 输入:寄存器R1和R2分别存放两个待相乘的数 ; 输出:寄存器R0存放相乘结果; 保存现场PUSH R1PUSH R2; 执行相乘操作MUL R0, R1, R2; 恢复现场POP R0POP R2POP R1; 返回RET3.3 子程序3:实现对一个数的平方根的计算assemblycalculate_sqrt:; 输入:寄存器R1存放待计算平方根的数 ; 输出:寄存器R0存放计算结果; 保存现场PUSH R1PUSH R0; 初始化结果为0XOR R0, R0; 循环计算平方根LDR R2, 1 ; 设定计算误差精度为1 sqrt_loop:; 比较结果的平方与待计算数的大小MUL R3, R0, R0CMP R3, R1; 结果满足精度要求,跳出循环BHI sqrt_done; 调整结果ADD R0, R0, R2; 继续循环B sqrt_loopsqrt_done:; 恢复现场POP R0POP R1; 返回RET4. 实验结果和分析经过上述子程序的设计和实现,我们实现了两个数相加、两个数相乘、以及一个数的平方根的计算功能。
子程序实验
lea di,string
inp:
mov ah,01h
int 21h
mov [di],al
inc di
cmp al,0dh
jnz inp
mov al,'$'
mov [di],al
ret
inputs endp
;--------------------------------------------------
3)利用宏指令改编程序以增强可读性,完成代码的时间和空间复杂度优化**。
3、实验过程或算法(源程序)
流程图:
源程序:
INCLUDE MACROOUT.LIB
;**************************************************
DATAS SEGMENT
string db 256 dup(?)
int 21h
ret
inputc endp
;--------------------------------------------------
outp proc near
mov ah,02h
int 21h
ret
outp endp
;--------------------------------------------------
ctrl proc nearmov dຫໍສະໝຸດ ,0ahmov ah,02h
int 21h
ret
ctrl endp
;--------------------------------------------------
CODES ENDS
;**************************************************
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验4 子程序实验一.实验目的1.掌握主程序与子程序之间的调用关系及调用方法;2.掌握子程序调用过程中近程调用与远程调用的区别;3.掌握通过堆栈转送参数的方法。
二.实验内容1.将BUF开始的10个单元中的二进制数转换成两位十六进制数的ASCII码,在屏幕上显示出来。
要求码型转换通过子程序HEXAC实现,在转换过程中,通过子程序DISP实现显示。
2.编写一个主程序,从键盘接收若干个字符,然后用远调用的方法,调用子程序统计字符串中字符’b’的个数.子程序的参数是字符串的首地址TABLE,字符串长度N及字符”b”.子程序返回字符"b”的个数.参数传送采用堆栈实现.主程序在子程序返回后,显示字符”b”及其个数(设为一位十六进制数)。
三.实验要求1.第一个实验程序用子程序的近程调用实现。
由于在调用HEXASC子程序时,子程序又调用了DISP子程序,这叫子程序的嵌套调用。
实验过程中可以从堆栈的内容看到两个子程序的返回地址值。
由于是近调用,地址值只包括返回地址的段内偏移量。
在每个子程序的执行中,检查CS值是不变的。
2.第二个程序是利用远调用的方法调用子程序的。
在远调用情况下,主程序与子程序处在不同的逻辑代码段中,可在子程序执行中查看CS值,它与主程序中的CS值是不同的。
子程序调用后,堆栈中保留了返回地址的段地址及段内偏移量。
3.第二个程序中,主程序与子程序之间参数的传送是由堆栈实现的。
一段是将参数(此处是串首址TABLE,串的长度N及待统计的字符“b”)顺序压如堆栈,在子程序调用后,通过BP指针对堆栈中的参数访问,并将统计的结果通过堆栈返回。
有关该方法的原理此处不再介绍。
4.预习子程序设计的基本方法,根据实验内容要求,画出子程序及主程序的流程图;熟悉键盘键入字符串及用堆栈传送参数的程序段编制方法。
四.实验环境PC微机DOS操作系统或Windows 操作系统MASM.EXE,LINK.EXE,或宏汇编集成环境五.实验步骤1.编辑、汇编两个源程序,生成相应的可执行文件(.EXE)2.用DEBUG的R命令,T命令或G命令和D命令检查远程调用及近程调用时堆栈的变化。
特别是通过堆栈传送的参数和子程序取出的参数是返回参数的详细过程。
3.检查程序执行的结果是否正确。
六.实验报告要求1.说明用堆栈传送参数的过程及其具体方法。
2.分析实验结果及所遇到问题,并说明解决的方法。
七.思考题分析远程调用与近程调用的区别,在用DEBUG有关命令观察时,执行过程有何不同。
参考程序清单1.码型转换程序清单:;CONV.ASNDATA SEGMENTBUF DB 0ABH,0CDH,0DEH,01H,02H,03HDB 3AH,4BH,5CH,6FHDATA ENDSCODE SEGMENTASSUME CS:CODE,DS:DATASTART:MOV AX,DATAMOV DS,AXMOV CX,10LEA BX,BUFAGAIN:MOV AL,[BX]CALL HEXASCINC BXLOOP AGAINMOV AH,4CHINT 21HHEXASC PROC NEARMOV DL,ALPUSH CXMOV CL,4SHR DL,CLPOP CXCALL DISP ;显示高位HEX数MOV DL,ALAND DL,0FHCALL DISPRETHEXASC ENDPDISP PROPCMP DL,9JBE NEXTADD DL,7NEXT:ADD DL,30HMOV AH,2INT 21H ;显示RETDISP ENDPCODE ENDSEND START2.统计并显示某键入字符的个数的程序:;COUNTER.ASMDATA SEGMENTCHAR DB ‘b’BUF DB 50H,? ,50H DUP(?)DATA ENDSMCODE SEGMENTASSUME CS:MCODE,DS:DATA START:MOV AX,DATAMOV DS,AXLEA DX,BUFMOV AH,9INT 21HLEA SI BUFMOV CL,[SI+1]MOV CH,0 ;CX中为字符串长度INC SIINC SI ;SI指向串首址TABLEMOV AL,CHARMOV AH,0 ;AX中为待查字符PUSH SIPUSH CXPUSH AX ;参数送堆栈CALL CHECKPOP AX :统计个数在AL中MOV DL,CHARMOV AH,2INT 21HMOV DL,ALAND DL,0FHCMP DL,9JBE NEXTADD DL,7NEXT:ADD DL,30HMOV AH,2INT 21H ;显示统计个数MOV AH,4CHINT 21HM CODE ENDSSCODE SEGMENTASSUME CS:SCODECHECK PROC FARPUSH BPMOV BP,SPMOV SI,[BP+10]MOV CX,[BP+8]MOV AX,[BP+6]XOR AH,AHAGAIN:CMP AL.[SI]JNE NEXT1INC AHNEXT1:INC SILOOP AGAINMOV AL,AHMOV [BP+10],AXPOP BPRET 4CHECK ENDPEND START实验3中删除输入串中重复字符实例换成子程序书写形式DA TA SEGMENTSTR DB 80 DUP(?)LEN DW ?DA TA ENDSSTACK SEGMENT STACKDW 100 DUP(?)TOS EQU THIS WORDSTACK ENDSCODE SEGMENTASSUME CS:CODE,DS:DA TA,ES:DATA,SS:STACKSTART: MOV AX,DATAMOV DS,AXMOV ES,AX ;初始化数据段和附加段为同一段值MOV AX,STACKMOV SS,AX ;初始化堆栈段LEA SP,TOS ;初始化栈顶指针LEA SI,STR ;SI<=接收串的首地址;调用IN_STR子程序从键盘输入字符串CALL IN_STR;调用REPLACE子程序将输入字符串中重复出现字符替换为0CALL REPLACE;调用DELE子程序将那些被替换成0的字符去掉CALL DELE;调用ENDLINE子程序现实回车换行CALL ENDLINE;调用PRTSTR子程序输出结果CALL PRTSTRMOV AH,4CHINT 21H;========================================================= ; 子程序: IN_STR; 功能: 从键盘输入字符串,以回车结束输入; 入口参数: SI = 输入字符串的首地址; 出口参数: SI = 输入字符串的首地址; CX = 输入字符个数;========================================================= IN_STR PROC NEAR;保护现场PUSH AXPUSH SIMOV CL,0 ;CL用来存放输入字符数AGAIN: MOV AH,1INT 21HCMP AL,0DHJZ IN_DONEMOV [SI],ALINC SIINC CLJMP AGAININ_DONE: MOV CH,0 ;CX存放输入字符数;恢复现场POP SIPOP AXRETIN_STR ENDP;=========================================================; 子程序: REPLACE; 功能: 把字符串中重复出现的字符用0替代; 入口参数: SI = 字符串的首地址; CX = 字符个数; 出口参数: 无;=========================================================REPLACE PROC NEAR ;将串中重复出现的字符用0替换;保护现场PUSH AXPUSH CXPUSH SIPUSH DIMOV DI,SIINC DIAGN: CMP CX,1JZ OK ;只有剩一个字符就结束替换PUSH CX ;保护外层循环计数MOV AL,[SI]AND AL,ALJZ NEXT ;当前字符已被替换为0L1: CMP AL,[DI]JNZ L2MOV BYTE PTR[DI],0L2: INC DILOOP L1 ;内部循环,扫描当前字符后面是否与当前字符相同,相同则用0替换NEXT: INC SIMOV DI,SIINC DIPOP CXLOOP AGNOK:;恢复现场POP DIPOP SIPOP CXPOP AXRETREPLACE ENDP;========================================================= ; 子程序: DELE; 功能: 去掉字符串中为0的字符; 入口参数: SI = 字符串的首地址; CX = 字符个数; 出口参数: 无;=========================================================DELE PROC NEAR;保护现场PUSH AXPUSH BXPUSH CXPUSH SIPUSH DIRPT: AND CX,CXJZ RTN ;CX=0结束子程序MOV AL,[SI]AND AL,ALJNZ NEXT1 ;当前字符不是被替换为0的字符PUSH CXMOV DI,SIXOR BX,BXCLDREPZ SCASBJNZ L3POP CXJMP RTN ;后面全是0,不用再继续L3: DEC DIMOV AL,[DI]MOV [SI],ALMOV BYTE PTR[DI],0POP CXNEXT1:INC SIDEC CXJMP RPTRTN: ;恢复现场POP DIPOP SIPOP CXPOP BXPOP AXRETDELE ENDP;========================================================= ; 子程序: PRTSTR; 功能: 输出字符串; 入口参数: SI = 字符串的首地址; CX = 字符个数; 出口参数: 无;========================================================= PRTSTR PROC NEAR;保护现场PUSH AXPUSH CXPUSH SIMOV AH,2LOP:MOV DL,[SI]CMP DL,0JZ EXTINT 21HINC SILOOP LOPEXT:;恢复现场POP SIPOP CXPOP AXRETPRTSTR ENDP;========================================================= ; 子程序: ENDLINE; 功能: 现实回车换行; 入口参数: 无; 出口参数: 无;========================================================= ENDLINE PROC NEAR;保护现场PUSH AXPUSH DXMOV AH,2MOV DL,0AHINT 21HMOV AH,2MOV DL,0DHINT 21H;恢复现场POP DXPOP AXRETENDLINE ENDPCODE ENDSEND START。