实验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)实验一keil软件平台实验 (2)实验二按键控制实验 (10)实验三查表实验 (12)实验四中断实验 (14)附录......................................................................................................... 错误!未定义书签。
安全注意事项1、不要在实验室吃东西。
2、不要穿拖鞋进入实验室,下雨天雨伞不要带入实验室。
3、使用实验箱时轻拿轻放,插拔排线时,对准,不要把排针插歪或者弄折,同时注意别被排针扎手。
4、接线时,必须把实验箱电源关闭。
5、下课后整理实验箱,设备,导线,椅子归原位,电脑正常关机,产生的垃圾带走。
实验一keil软件平台实验一、实验目的认识单片机MCS-51最小系统的构成和相关的开发软件。
任何一个用户系统的开发都需要一个界面良好的调试平台,以方便地、快捷地完成系统的设计与调试。
单片机的开发也是如此。
Keil是目前最流行,使用最广泛的开发平台,也是我们学习单片机的良好工具。
因此,我们必须首先熟悉这个工具,掌握这个工具。
二、实验内容及原理(一)实验内容要求实现某一个I/O口控制八个LED发光二极管左移或者右移流水。
(二)实验原理实验是通过对一些简单程序的调试,帮助我们直观地了解与掌握Keil调试软件的基本功能,掌握如何利用Keil来调试应用系统的硬件与软件的基本方法。
1、硬件(1)实验箱开发板主控芯片采用单片机型号为STC89C52RC,总共四组八位并行I/O口,均可实现数据输入输出,一个全双工串口,可支持的振荡频率范围为2~48Mhz,具有三个16位可编程定时器/计数器,八个中断源,四级优先级,其引脚分布如图1-1所示。
此外实验箱开发板还配备了共阴极数码管显示模块、共阳极八字形流水灯模块、点阵模块、独立按键模块、矩阵按键模块、LCD1602液晶显示模块、蜂鸣器、实时时钟模块、直流电机模块、A/D转换模块等外围模块、超声波模块、温度传感器模块等,可供相关实验与单片机配合使用。
汇编程序实验4_查找电话号码

一、实验目的学习用汇编语言设计与编写子程序二、实验要求(1) 要求程序建立一个可存放50项的电话号码表,每项包括人名(20个字符)及电话号码(8个字符)两部分;(2) 程序可接收输入人名及相应的电话号码,并把它们加入电话号码表中;(3) 凡有新的输入后,程序应按人名对电话号码表重新排序;(4) 程序可接收需要查找电话号码的人名,并从电话号码表中查出其电话号码,再在屏幕上以如下格式显示出来。
name tel.X X X X X X X X三、实验提示:(1)显示提示符’Input name:’;(2)调用子程序 input_name 接收人名;(3)调用子程序 stor_name 把人名存入电话号码表 tel_tab 中:(4)显示提示符’Input a telephone number:’;(5)调用子程序 inphone 接收电话号码,并把它存入电话号码表tel_tab中;(6)如输入已结束则调用 name_sort 子程序对电话号码表接人名排序;(7)显示提示符’Do you want a telephone number ?(Y/N)’;(8)回答N收退出程序;(9)回答Y则再显示提示符’name ?’;(10)调用子程序 input_name接收人名;(11)调用子程序 name_search 在电话号码表中查找所要的电话号码;(12)调用子程序 printline 按要求格式显示人名及电话号码;(13)重复查号提示符直至用户不要求查号为止。
四、实验程序datarea segmenttel_name label bytemaxnlen db 20namelen db ?namefld db 21 dup(?) ;定义20个字符的用于存放人名的字符串tel_num label bytemaxtlen db 8tellen db ?telfld db 9 dup(?) ;定义8个字符的用于存放电话号码的字符串tel_tab db 50 dup(20 dup(' '), 8 dup(' ')) ;定义可存放50项纪录的电话号码表tel_sav db 28 dup(?), 13, 10, '$'list db 20 dup(' '), 8 dup(' '), 0dh, 0ah, '$' ;定义电话号码表的每个条目string1 db 'Input name:', '$'string2 db 'Input a telphone number:', '$'string3 db 'Do you want a telephone number?(Y/N)', '$'string4 db 'name?', '$'string5 db 'Would you like to input a telephone list?(Y/N)', '$'string6 db 'The Tel_Lab is empty.', '$'string7 db 'There is no list fitting.', '$'string8 db 'name tel. ', '$'string9 db 'Do you want a Tel_Lab?(Y/N)', '$'endadd dw ?swapped db 0tel_count db 0 ;计算电话号码表中的条目数量datarea endsprognam segmentmain proc far ;主程序assume cs: prognam, ds: datarea, es: datareastart:push dssub ax, axpush axmov ax, datareamov ds, axmov es, axcldlea di, tel_tab ;将电话号码表传给目的变址寄存器cho_inp: ;进行选择,是否输入条目mov ah, 09lea dx, string5int 21h ;输出“Would you like to in put a telephone list?(Y/N)”mov ah, 01int 21h ;输入,进行选择mov dl, 4ehcmp al, dlje sort_n ;若输入为N,则跳转至sort_n,进行电话号码表的排序mov dl, 6ehcmp al, dlje sort_n ;若输入为n,则同上mov dl, 59hcmp al, dlje input_n ;若输入为Y,则跳转至input_n,进行电话号码条目的输入mov dl, 79hcmp al, dlje input_n ;若输入为y,则同上mov ah, 02mov dx, 0dhint 21hmov dx, 0ahint 21hjmp cho_inp ;若输入不为Y(y)/N(n),则返回cho_inp,重新进行选择input_n: ;输入人名,并保存mov ah, 02mov dx, 0dhint 21hmov dx, 0ahint 21hmov ah, 09lea dx, string1int 21h ;输出“Input name:”call input_name ;调用子程序input_name接收人名call stor_name ;调用子程序stor_name把人名存入电话号码表tel_tab中input_p: ;输入电话号码,并保存lea dx,string2mov ah, 09int 21h ;输出“Input a telephone number:”call inphone ;调用子程序inphone接收电话号码,并把它存入电话号码表tel_tab 中jmp cho_inp ;跳转至cho_inp,按提示选择是否继续输入条目sort_n: ;对电话号码表进行排序mov ah, 02mov dx, 0dhint 21hmov dx, 0ahint 21hcall name_sort ;调用子程序name_sort,对电话号码表按人名排序print_lab: ;输出整个电话号码表lea dx, string9mov ah, 09int 21h ;输出“Do you want a tel_lab?(Y/N)”mov ah, 01int 21h ;输入,进行选择mov cl, almov ah, 02mov dl, 0dhint 21hmov ah, 02mov dl, 0ahint 21hmov al, clmov dl, 4ehcmp al, dlje search_n ;若输入为N,则跳转至search_n,进行电话号码的查找mov dl, 6ehcmp al, dlje search_n ;若输入为n,则同上mov dl, 59hcmp al, dlje goon_p ;若输入为Y,则跳转至goon_p,继续该部分操作mov dl, 79hcmp al, dlje goon_p ;若输入为y,则同上jmp print_lab ;若输入不为Y(y)/N(n),则跳转至print_lab,重新进行选择goon_p: ;继续输出电话号码表的操作call printall ;调用子程序printall,输出整个电话号码表search_n: ;查找电话号码条目lea dx, string3mov ah, 09int 21h ;输出“Do you want a telephone number?(Y/N)”mov ah, 01int 21h ;输入,进行选择mov cl, almov ah, 02mov dl, 0dhint 21hmov ah, 02mov dl, 0ahint 21hmov al, clmov dl, 4ehcmp al, dlje exit ;若输入为N,则跳转至exit,退出程序mov dl, 6ehcmp al, dlje exit ;若输入为n,则同上mov dl, 59hcmp al, dlje goon_s ;若输入为Y,则跳转至goon_s,继续该部分操作mov dl, 79hcmp al, dlje goon_s ;若输入为y,则同上jmp search_n ;若输入不为Y(y)/N(n),则跳转至search_n,重新进行选择goon_s: ;继续查找操作lea dx, string4mov ah, 09int 21h ;输出“name?”mov ah, 02mov dl, 0dhint 21hmov ah, 02mov dl, 0ahint 21hcall input_name ;调用子程序input_name,接收人名call name_search ;调用子程序name_search,对电话号码表按人名进行查找jmp search_n ;跳转至search_n,继续进行查找exit: ;退出程序retmain endpinput_name proc near ;子程序input_name,用于接受人名mov ah, 0ahlea dx, tel_nameint 21h ;输入人名mov ah, 02hmov dl, 0dhint 21hmov dl, 0ahint 21hmov bh, 0mov bl, namelenmov cx, 20sub cx, bxnamebrk: ;将人名除外所剩下的字符用空格填满mov namefld[bx], 20hinc bxloop namebrkretinput_name endpstor_name proc near ;子程序stor_name,用于把人名存入电话号码表tel_tab中inc tel_count ;将人名存入电话号码之后,电话号码条目数量增1cldlea si, namefldmov cx, 10rep movswretstor_name endpinphone proc near ;子程序inphone,用于接受电话号码,并把它存入电话号码表tel_tab 中mov ah, 0ahlea dx, tel_numint 21h ;输入电话号码mov ah, 02hmov dl, 0dhint 21hmov dl, 0ahint 21hmov bh, 0mov bl, tellenmov cx, 8sub cx, bxtelbrk: ;将电话号码数字除外,所剩下的字符用空格填满mov telfld[bx], 20hinc bxloop telbrkcldlea si, telfldmov cx, 4rep movswretinphone endpname_sort proc near ;子程序name_sort,用于对电话号码表按人名排序sub di, 56mov endadd, dicmp al, 0je emptystart_sort:mov swapped, 0lea si, tel_tabcmp_n:mov cx, 20mov di, siadd di, 28mov ax, dimov bx, sirepe cmpsbjbe no_exchgcall exchange_name ;调用子程序exchang_name,将两个相邻的条目进行对调jmp no_exchgempty: ;若电话号码表为空mov ah, 09lea dx, string6int 21h ;输出“The tel_lab is empty.”jmp exit_sortno_exchg: ;不进行对调mov si, axcmp si, endaddjbe cmp_ncmp swapped, 0jnz start_sortexit_sort:retname_sort endpexchange_name proc near ;子程序exchange_name,用于将电话号码表中的两个相邻的条目进行对调mov cx, 14mov si, bxrep movswmov cx, 14mov di, bxrep movswmov cx, 14lea si, listrep movswmov swapped, 1retexchange_name endpname_search proc near ;子程序name_search,用于按人名在电话号码表中查找所要的电话号码push dimov al, tel_countlea si, tel_tabagain:cmp al, 0je no_listmov cx, 20lea di, namefldmov bx, sirepz cmpsbjb find_nja no_listdec almov ah, 09lea dx, string8int 21h ;输出“name tel. ”mov ah, 02mov dl, 0dhint 21hmov dl, 0ahint 21hcall printline ;调用子程序printline,输出所查找到的条目jmp exit_schfind_n:mov si, bxjmp againno_list: ;若不存在该条目mov ah, 09lea dx, string7int 21h ;输出“There is no list fitting.”mov ah, 02mov dl, 0dhint 21hmov dl, 0ahint 21hexit_sch:pop diretname_search endpprintline proc near ;子程序printline,用于输出所查找到的电话号码条目mov si, bxlea di, listmov cx, 14rep movswmov ah, 09lea dx, listint 21hretprintline endpprintall proc near ;子程序printall,用于输出整个电话号码表push dimov ah, 09lea dx, string8int 21hmov ah, 02mov dl, 0dhint 21hmov dl, 0ahint 21hmov bl, tel_countcmp bl, 0je empty_lablea si, tel_tabnext:lea di, listmov cx, 14rep movswmov ah, 09lea dx, listint 21hdec bljnz nextjmp exit_pallempty_lab:mov ah, 09lea dx, string6int 21hexit_pall:pop diretprintall endpprognam endsend start五、模块说明主函数main:用来显示用户操作提示,调用子模块,使程序完成查找电话号码的过程接收人名函数input_name:输入人名,将此人名保存至缓冲区,并用空格补足保存人名函数stor_name:将人名从缓冲区中取出,保存在电话号码表中的人名区中接收并且保存电话号码函数inphone:输入电话号码,将此电话号码保存至缓冲区,并用空格补足,然后,将电话号码从缓冲区中取出,保存在电话号码表中的电话号码区中电话号码表排序函数name_sort:运用冒泡法,对电话号码表按人名排序对调条目位置函数exchange:将不符合排序规律的条目的位置进行调整查找电话号码函数name_search:输入人名,在电话号码表中依次比较人名进行查找输出电话号码条目函数printline:查找到条目之后,将条目输出输出电话号码表函数printall:将整个电话号码表的所有条目依次输出六、模块层次图七、调试结果。
子程序设计实验报告

子程序设计实验报告
子程序设计实验报告
介绍
本次实验旨在通过设计和实现子程序来加深对函数和过程的理解,并通过实际编程实践来掌握子程序设计的具体方法和技巧。
实验过程
步骤1:问题分析
需要分析并确定实验所要解决的问题,明确问题的输入和输出要求。
步骤2:设计子程序
根据问题的分析结果,设计相应的子程序。
需要考虑到子程序的输入参数和返回值,并根据需要进行格式化输出。
步骤3:编写主程序
在主程序中调用已设计的子程序,并根据具体情况进行输入和输出的处理。
步骤4:调试和测试
完成程序的编写后,进行调试和测试。
通过输入不同的测试数据,检查程序的输出是否符合要求,对程序进行必要的调整和修改。
步骤5:和提交
整理实验过程中的思考和实践,实验的收获和体会,并按要求
提交实验报告。
实验结果
根据实验的要求,我们采用了合适的子程序设计方法,成功地
实现了所需的功能,得到了符合预期的实验结果。
实验
通过本次实验,我们对子程序设计有了更深入的理解,学会了
合理地划分和设计子程序,在实践中提高了编程的技巧和能力。
参考资料
1. Markdown语法指南:
2. C语言函数和过程的概念:。
子程序设计实验报告

子程序设计实验报告子程序设计实验报告一、实验目的本实验旨在通过实践学习子程序设计的基本原理和方法,并掌握在程序中编写和调用子程序的技巧。
二、实验环境及工具1-操作系统:Windows 102-集成开发环境(IDE):Visual Studio Code3-编程语言:C++三、实验内容1-子程序的定义和调用2-子程序的参数传递方式3-子程序的返回值4-子程序的递归调用5-子程序的调试技巧四、实验步骤1-子程序的定义a-定义子程序的语法格式b-编写一个简单的子程序示例2-子程序的调用a-了解调用子程序的方式b-调用之前的准备工作c-编写一个完整的程序,调用已定义的子程序3-子程序的参数传递方式a-值传递b-引用传递c-指针传递d-编写不同参数传递方式的子程序示例4-子程序的返回值a-子程序的返回值类型和语法格式b-编写一个子程序,并返回一个值5-子程序的递归调用a-了解递归调用的概念和优点b-编写递归调用的子程序6-子程序的调试技巧a-使用调试工具进行单步跟踪b-设置断点c-使用调试输出语句辅助调试五、实验结果与分析1-对每个实验步骤进行实验,并记录实验结果2-分析实验结果,总结子程序设计的特点和应用场景六、实验总结通过本次实验,我对子程序设计有了更深入的了解,并掌握了基本的子程序编写和调用技巧。
子程序设计在程序开发中起到了重要的作用,在提高代码的模块化和可重用性方面具有显著优势。
七、附件本文档无附件。
八、法律名词及注释1-子程序:也称为函数或方法,是封装了一段代码的独立执行单元,可以接受输入参数并返回一个值。
2-调试:在程序开发过程中,通过排除错误和异常情况,使程序正常运行的过程。
子程序及其调用实验

实验二 子程序及其调用实验一、 实验目的1、通过编辑练习常用指令,理解并掌握MCS-51单片机的指令系统。
2、掌握子程序调用的程序设计。
3、掌握子程序调用过程中保护现场与恢复现场以及调用程序与被调用程序之间的参数传递。
4、学习汇编语言的程序设计方法二 、实验设备计算机操作系统:Windows xp应用软件:WAVE6000三 、实验内容编写程序,计算2^i a Y ∑=。
a1,a2,...,a10存放在内部RAM 的20H 开始的存储区内,计算所得结果放入R2和R3中。
四、实验源程序ORG 0000HMAIN: MOV R0,#20HMOV R7,#10HMOV R3,#0MOV R2,#0MOV 20H,#05HMOV 21H,#04HMOV 22H,#03HMOV 23H,#02HMOV 24H,#01HMOV 25H,#09HMOV 26H,#08HMOV 27H,#07HMOV 28H,#06HMOV 29h,#00HLOOP: MOV A ,@R0ACALL SORTADD A,R2MOV R2,ACLR AADDC A,R3MOV R3,AINC R0DJNZ R7,LOOPSJMP $SORT: MOV DPTR,#TABMOVC A,@A+DPTRRETTAB: DB 0,1,4,9,16,25,36,49,64,81五、实验结果与分析本次实验是计算0到9的平方和,实验结果为011D,与计算结果相符。
子程序调用不必重复编写同样的程序,有利于提高编码效率,缩短源程序与目标程序的长度,节省程序存储的空间,使程序模块化、通用化,便于阅读、交流。
六、实验心得通过这次实验,我理解并掌握了子程序调用的程序设计,掌握子程序调用过程中保护现场与恢复现场以及调用程序与被调用程序之间的参数传递。
子程序调用能很好的提高编码效率,节省程序存储的空间,应该多加练习,熟练掌握。
(注:专业文档是经验性极强的领域,无法思考和涵盖全面,素材和资料部分来自网络,供参考。
PLC实验报告:四节传送带的模拟-毕业设计(论文)word格式

(一)、四节传送带的模拟有一个用四条皮带运输机的传送系统,分别用四台电动机带动,控制要求如下:1、启动是先启动最末一条皮带机,经过五秒时,再依次起动其他皮带机。
2、停止时应先停止最前一条皮带机,待料运送完毕后,再依次停止其他皮带机。
3、当某条皮带机发生故障时,该皮带机及其前面的皮带机立即停止。
而该皮带机以后的皮带机待运完后才停止。
例如M2故障,M2,M1立即停止,经过5秒后,M3停,再过5秒,M4停。
当某条皮带机上有重物时,该皮带机前面的皮带机停止,该皮带机运行5秒后停,而该皮带机以后的皮带机待料运完后才停止。
例如M3上有重物,M1,M2立即停止,再过5秒M4停止。
(一)、实训目的了解传送带的结构,传送带的工作原理。
通过使用各基本指令,进一步熟练掌握PLC的编程和程序调试(二)、实训要求1,确定I/O点。
2分配I/O地址。
3画出PLC与I/O的链接线图。
4编程,上机调试。
(三)、实训设备1、THSMS-A型、THSMS-B型实验装置一台2、安装了STEP7-Micro/WIN32编程软件的计算机一台3、PC/PPI编程电缆一根4、锁紧导线若干(四)实验内容:1,确定I/O点6个I点分别为:SB1(启动),SB2(停止),A(M1故障输入),B(M2故障输入),C(M3故障输入),D(M4故障输入)。
4个O点分别为:M1,M2,M3,M42,分配I/O地址。
3,PLC与I/O的连接线图4,程序(梯形图,语句表)ORGANIZATION_BLOCK 主程序:OB1TITLE=程序注释BEGINNetwork 1 // 网络标题// 网络注释LPSTON T37, 50LRDTON T38, 100 LPPTON T39, 150 Network 2TON T40, 50 Network 3LD T40TON T41, 50 Network 4LD T41TON T42, 50 Network 5LD T42Network 6LD T37Network 7LD T38Network 8LD T39END_ORGANIZATION_BLOCK SUBROUTINE_BLOCK SBR_0:SBR0TITLE=子程序注释BEGINNetwork 1 // 网络标题// 网络注释END_SUBROUTINE_BLOCK INTERRUPT_BLOCKINT_0:INT0TITLE=中断程序注释BEGINNetwork 1 // 网络标题// 网络注释END_INTERRU PT_BLOCK5、程序设计及工作过程分析按下启动按钮SB1,动合触点闭合,保持闭合,皮带机M4运动,此时T37开始计时,5s后皮带机M3起动,依次通过计时器T38,T39控制皮带机M2,M1的起动。
汇编语言实验报告(子程序)

西安财经学院信息学院
《汇编语言程序设计》 实验报告
实验名 子程序结构程序设计 实验室 实验楼403 实验日期 2013/06/09 一、实验目的及要求
1. 学习子程序的编写,主子程序的调用
2. 不同模块间程序的调用和调试
二、实验环境
硬件环境:一台微型计算机; 软件环境:windows 7 链接程序:LINK.EXE
调试环境:DOSBOX 虚拟平台。
三、实验内容
数据段中的
6个字符,“ABCDEF ”,调用子程序将其逐个显示出来。
子程
序的功能是显示一个字符。
四、实验过程
1. 通过编译程序、链接程序分别生成OBJ 和EXE 文件后,直接运行查看结果
如下:
2. 反汇编,查看程序的指令,如下所示:
姓名 学号 10051704 班级 计本1004班 指导教师 张娟
3. 用-d 查看数据段内存放的数据:
4. 单步执行
查看堆栈段的内容:继续单步执行:
五、源程序清单
程序源代码如下:
DATA SEGMENT
MAG DB ‘ABC DEF’
DATA ENDS
CODE SEGMENT
ASSUME CS: CODE, DS: DATA
START: MOV AX, DATA
MOV DS, AX
MOV SI, 0
MOV CX, 6
LL: MOV DL, MAG[SI]
CALL MADD
INC SI
LOOP LL
MOV AH, 4CH
INT 21H
MADD PROC。
实验报告 子程序设计实验

实验报告子程序设计实验实验报告:子程序设计实验一、实验目的本次实验的主要目的是深入理解和掌握子程序设计的概念、原理和方法,通过实际编程实现,提高我们的编程能力和问题解决能力。
二、实验环境本次实验使用的编程语言为 Python,开发工具为 PyCharm。
操作系统为 Windows 10。
三、实验内容(一)简单函数的定义与调用首先,我们定义了一个简单的函数来计算两个数的和。
```pythondef add_numbers(a, b):return a + b```然后,通过调用这个函数来计算并输出结果。
```pythonresult = add_numbers(5, 3)print("两数之和为:", result)```(二)带参数的函数接下来,定义了一个函数可以根据给定的半径计算圆的面积。
```pythonimport mathdef calculate_area(radius):return mathpi radius 2```调用该函数计算半径为 4 的圆的面积并输出。
```pythonarea = calculate_area(4)print("半径为 4 的圆的面积为:", area)```(三)函数的返回值定义了一个函数,判断一个数是否为偶数。
```pythondef is_even(number):if number % 2 == 0:return Trueelse:return False```调用该函数对多个数进行判断并输出结果。
(四)函数的嵌套调用定义了两个函数,一个函数计算两个数的平均值,另一个函数判断一个数是否大于平均值。
```pythondef calculate_average(a, b):return (a + b) / 2def is_greater_than_average(number, a, b):average = calculate_average(a, b)if number > average:return Trueelse:return False```通过调用这两个函数进行相应的计算和判断。
- 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。