串处理与子程序
AT24C02串行E2PROM的工作原理与读写

AT24C02串行E2PROM的工作原理与读写串行EEPROM中,较为典型的有ATMEL公司的AT24CXX系列和AT93CXX等系列产品。
简称I2C总线式串行器件。
串行器件不仅占用很少的资源和I/O线,而且体积大大缩小,同时具有工作电源宽、抗干扰能力强、功耗低、数据不易丢失和支持在线编程等特点。
I2C总线是一种用于IC器件之间连接的二线制总线。
它通过SDA(串行数据线)及SCL (串行时钟线)两根线在连到总线上的器件之间传送信息,并根据地址识别每个器件:不管是单片机、存储器、LCD驱动器还是键盘接口。
1.I2C总线的基本结构:采用I2C总线标准的单片机或IC器件,其内部不仅有I2C接口电路,而且将内部各单元电路按功能划分为若干相对独立的模块,通过软件寻址实现片选,减少了器件片选线的连接。
CPU不仅能通过指令将某个功能单元电路挂靠或摘离总线,还可对该单元的工作状况进行检测,从而实现对硬件系统的既简单又灵活的扩展与控制。
I2C总线接口电路结构如图1所示。
从图中可以看出:对于时钟及数据传送,串行数据I/O端SDA一般需要用外部上拉电阻将其电平拉高。
2.双向传输的接口特性:传统的单片机串行接口的发送和接收一般都分别用一条线,如MCS51系列的TXD和RXD,而I2C总线则根据器件的功能通过软件程序使其可工作于发送或接收方式。
当某个器件向总线上发送信息时,它就是发送器(也叫主器件),而当其从总线上接收信息时,又成为接收器(也叫从器件)。
主器件用于启动总线上传送数据并产生时钟以开放传送的器件,此时任何被寻址的器件均被认为是从器件。
I2C总线的控制完全由挂接在总线上的主器件送出的地址和数据决定。
总线上主和从(即发送和接收)的关系不是一成不变的,而是取决于此时数据传送的方向。
SDA和SCL均为双向I/O线,通过上拉电阻接正电源。
当总线空闲时,两根线都是高电平。
连接总线的器件的输出级必须是集电极或漏极开路,以具有线“与”功能。
汇编语言——子程序

6.2.2.2 RET指令 指令 【指令格式】RET 【功能】这是子程序返回指令,必须写在子程序的指令 序列之中。根据所在的子程序的类型不同,RET指令的功能 也分为两种情况: (1)如果RET所在子程序是NEAR类型,则从堆栈中出 栈一个字(当然,SP会加2),送给IP。 (2)如果RET所在子程序是FAR类型,则先从堆栈中出 栈一个字送到IP,再出栈一个字送到CS,栈顶指SP的值加4。
cr
PROC NEAR MOV AH,2 MOV DL,13 INT 21H MOV DL,10 INT 21H RET
cr ENDP main:MOV AX,dseg MOV DS,AX LEA DX,buf MOV AH,10 INT 21H CALL cr MOV AH,1 INT 21H MOV BL,AL ;输入一个字符 ;用BL保存读入的字符 ;输入一个符号串
【解】程序段(a)中,先把AX赋值为102H,再把BX赋 值为304H,然后用ADD指令把两数相加,和为406H,结果 放在ADD指令的目的操作数AX中。 程序段(b)的前两行与(a)完全相同,AX取值102H,BX 取值304H,但在相加之前调用了子程序cr。从例6.3中cr的 具体实现方法可以知道,调用过程中寄存器AH的值被改为 2,因为INT 21H输出功能,使AL的值也被修改,变成0AH, 并且这个值一直保持到调用结束,于是“CALL cr”指令调 用子程序后,AX的值不再是调用前的102H,而变成了 20AH,当ADD指令进行两个寄存器相加时,结果是50EH, 并放到目的操作数AX中。
6.3 应用子程序进行编程
6.3.1 子程序实例
【例6.3】分析下列程序,描述它的功能。 dseg SEGMENT buf DB 80,81 DUP(0) dseg ENDS sseg SEGMENT STACK DW 64 DUP(0) sseg ENDS cseg SEGMENT ASSUME CS:cseg,DS:dseg,SS:sseg
汇编语言溢出小结

汇编语言溢出小结汇编溢出使用总结如下:执行加法指令ADD:OF标志位根据操作数的符号及其变化情况来设置:若两个操作数的符号相同,而结果的符号与之相反时,OF=1,否则OF=0。
溢出位既然是根据数的符号及其变化来设置的,当然他使用来表示带符号数的溢出的。
执行减法指令SUB:减法的OF位的设置方法为:若两个数的符号相反,而结果的符号与减数的符号相同,则OF=1,除上述情况外OF=0。
OF=1说明带符号数的减法运算结果是错误的。
求补运算指令NEG:NEG指令的条件码按求补后的结果设置,只有当操作数为0时,求补运算结果使CF=0,其他情况均为CF=1.所以,只有当字节运算时对-128求补,以及字运算时对-32768求补和双字运算时对-2的31次方求补的情况下OF=1,其他则OF=0。
无符号乘法指令MUL:对于MUL指令,如果乘积的高一半为0,几字节操作的(AH)或字操作的(DX)或双字的(EDX)为0,则CF位和OF位均为0;否则,均为1.带符号数乘法指令IMUL:对于IMUL指令,如果乘积的高一半是低一半的符号扩展,则CF位和OF位均为0,否则为1.除法指令:除法指令对所有条件码位均无定义。
但是需要注意一个问题,如果字节操作时,被除数的高8位的绝对值》除数的绝对值;或者字操作时,被除数的高16为绝对值》除数的绝对值,则商就会产生溢出。
在8086系统中,这种溢出是由系统直接转入0型中断处理的。
为避免这种情况,必要时程序应进行溢出判断及处理。
逻辑运算指令:AND,OR,NOT,XOR,TESTT中,NOT不影响标志位,其他4种指令将使CF位和OF位为0.移位指令:OF位只有当移位次数CNT=1时,即移动一位的时候才是有效的,否则该位无定义。
当CNT=1时,在移位后最高有效位的值发生变化时(原来为0,移位后为1;或原来为1,移位后为0)OF=1,否则值为0.串处理指令:MOVS,LODS,STOS,INS,OUTS不影响标志位。
子程序的调用

mov ax,data mov ds,ax call nearp lea ax,nearp call ax call nproc lea bx,nproc call word ptr [bx]
call farp call fproc lea bx,fproc
Nearp proc near
…… ret Nearp endp Code1 ends end main code2 segment
3)在调用时,NEAR 和FAR 可以强制改变 CALL FAR PTR NEARPROC CALL NEAR PTR FARPROC
子过程的调用与返回指令
子过程的调用是个”有去有回”的过程,子程序执行
完后必须返回CALL指令的下一条指令处,因此必须对
CALL指令的下条指令的地址进行保存.保存地址的操作 是通过堆栈来完成.不是采用PUSH \POP指令来实现,而
通过存储器来传递参数
当调用程序和子程序处于同一文件中,可以直接访问 块内的变量或数据。 举例3:编写程序从键盘上输入一个字符串,存于变量为INPUT中, 要求以回车键作为输入过程的结束,字符结尾部分添加0。 (1) 分析: 子程序getstring直接从键盘输入字符串,入口参数:无。出 口参数:字符串变量INPUT 变量INPUT 属于通过存储器传递参数,调用程序和子程序处 于同一文件在数据段定义变量属于局部变量
Findmax proc
mov ax,[si] Lp1: cmp ax,[si+2] jg next xchg ax,[si+2] next: add si,2 loop lp1 ret findmax endp Code ends
end main
参数的传递
8周参考:常用指令(串操作 程序控制指令 处理器控制指令)

1000H
41 42 43 44 45 46
. . .
’ A ’ B’ ’ ’C’ ’ D’ E’ ’ ’ F’
实现题目要求的程序段调试
9
MOV DI, 1000H MOV CX, 0AH MOV AL, ’E’ CLD REPNZ SCASB JZ FOUND MOV DL, ’N’ JMP DONE FOUND:DEC DI MOV ADDR, DI SUB DI, 1000H INC DI MOV NUM, DI MOV DL, ’Y’ DONE: MOV AH, 2 INT 21H HLT
31
例1:给1A000H开始的256个内存单元均减去1,若 发现某个单元减为0则立即退出循环,其后的单元 不再减1。程序段如下:(逻辑地址为1A00:0H)
MOV AX, 1A00H MOV DS, AX MOV DI, -1 MOV CX, 256 GOON: INC DI DEC BYTE PTR[DI] LOOPNZ GOON HLT
条件转移指令可实现程序的条件分支。
条件转移指令根据标志位的状态来决定是否
进行分支转移。 格式: JXX label ;xx为条件名称缩写 指令的转移范围为-128~+127字节。 主要的条件转移指令。
24
① 根据单个标志位设置的条件转移指令
JB/JC JNB/JNC/JAE JP/JPE JNP/JPO JZ/JE JNZ/JNE JS JNS JO JNO ;低于,或CF=1,则转移 ;高于或等于,或CF=0,则转移 ;奇偶标志PF=1(偶),则转移 ;奇偶标志PF=0(奇),则转移 ;结果为零(ZF=1),则转移 ;结果不为零(ZF=0),则转移 ;SF=1,则转移 ;SF=0,则转移 ;OF=1,则转移 ;OF=0,则转移
汇编语言关键字

数据传送指令:负责把数据、地址或立即数传送到寄存器或存储单元中。
数据传送指令类型指令说明通用数据传送指令MOV(传送)、PUSH(进栈)、POP(出栈)、XCHG(交换)累加器专用传送指令IN(输入指令)、OUT(输入指令)地址传送指令LEA(有效地址送寄存器)、LDS(指针送寄存器和DS)、LES(指针送寄存器和ES)标志寄存器传送指令LAHF(标志送AH)、SAHF(AH送标志寄存器)、PUSHF(标志进栈)、POPF(标志出栈)2)算术指令:用来执行算术运算。
算术指令类型指令说明加法指令ADD(加法)、ADC(带进位加法)、INC(加1)减法指令SUB(减法)、SBB(带借位减法)、DEC(减1)、NEG(求补)、CMP(比较)乘法指令MUL(无符号数乘法)、IMUL(带符号数乘法)除法指令DIV(无符号数除法)、IDIV(带符号数除法)、CBW(字节转换为字)、CWD(字转换为双字)3)逻辑指令:对字或字节执行逻辑运算。
逻辑指令类型指令说明逻辑运算指令AND(逻辑与)、OR(逻辑或)、NOT(逻辑非)、XOR(异或)、TEST(测试)移动指令SHL(逻辑左移)、SAL(算术左移)、SHR(逻辑右移)、SAR(算术右移)、ROL(循环左移)、ROR (循环右移)、RCL(带进位循环左移)、RCR(带进位右移)4)串处理指令:处理存放存储器里的数据串。
串处理指令类型指令说明指令MOVS(串传送)、CMPS(串比较)、SCAS(串扫描)、LODS(从串取)、STOS(存入串)5)控制转移指令:用来控制程序的执行流程。
控制转移指令类型指令说明无条件转移指令JMP(段间和段内转移)条件转移指令JZ(结果为0(或相等)则转移)、JS(结果为负则转移)、JNS(结果为正则转移)、JO(溢出则转移)、JNO(不溢出则转移)、JP(奇偶位为1则转移)、JNP(奇偶位为0则转移)循环指令LOOP(循环指令)、LOOPPZ/LOOPE(当为0或相等时循环指令)、LOOPNZ/LOOPNE(当不为0或不相等时循环指令)子程序指令CALL(调用指令)、RET(返回指令)中断指令INT(中断)、INTO(如溢出则中断)、RIET(从中断返回)6)处理机控制指令:处理机控制指令类型指令说明标志处理指令CLC(进位位置0指令)、CMC(进位位求反指令)、STC(进位位置为1指令)、CLD(方向标志置1指令)、STD(方向标志位置1指令)、CLI(中断标志置0指令)、STI(中断标志置1指令)其他处理机控制指令NOP(无操作)、HLT(停机)、WAIT(等待)、ESC(换码)、LOCK(封锁)。
指令的种类
3.堆栈操作指令
4.输入/输出指令
★统一编址 当内存与接口地址统一编址时,内存与接口同属于一个 地址空间,用于内存的指令原则上均可用于接口。 ★独立编址 当内存与接口地址采用独立编址时,它们的地址是相互 独立的。
指令的种类
1.2 算术运算类指令
格式
MOVS/MOVSB/MOVSW
串 操
CMPS/CMPSB/CMPSW
作
SCAS/SCASB/SCASW
指
令
LODS/LODSB/LODSW
STOS/STOSB/STOSW
名称 串传送指令 串比较指令 串扫描或串搜索指令 串装入指令 字串存储指令
指令的种类
1.8 位操作指令
位操作指令是对某一位进行操作的指令,也就是对一个字 (字节)中的某一位进行操作的指令。
格式
操作
标
HLT
使处理器处于停止状态, 不执行指令
志
位 WAIT 使处理器处于等待状态
操 作 指
LOCK
封锁总线指令,可放在 任一指令前作为前缀
令
NOP
空操作指令,处理器什 么操作也不做
指令的种类
1.7 串操作指令
在存储器中存放的一串字或字节可以是二进制数,也可以是 BCD码或ASCⅡ码。它们存放在某一个连续的内存区中,若对它 们的每字或字节均进行同样的操作,该操作就称串操作。
XOR指令对两个操作数进 行按位异或运算。
指令的种类
1.4 移位、循环类指令
CF
位移指令SAL/SHL操作示意图
CF
SAR操作示意图
CF 0
SHR操作示意图
指令的种类
VBA函数和子程序的编写与调用
VBA函数和子程序的编写与调用在计算机编程领域中,VBA(Visual Basic for Applications)是一种常用的编程语言,可用于微软的Office套件中的各种应用程序,如Excel、Word和PowerPoint。
VBA函数和子程序是VBA编程中的重要组成部分,能够帮助我们简化和优化代码,提高工作效率。
本文将详细介绍VBA函数和子程序的编写与调用。
VBA函数是一段可重复使用的代码,它接受一个或多个参数,并返回一个值。
我们可以将函数视为一个封装好的计算过程,通过传入不同的参数来获取不同的计算结果。
编写VBA函数的基本语法如下:```Function 函数名(参数1, 参数2, ...) As 数据类型' 函数的代码块' ...' 计算结果通过赋值给函数名实现End Function在定义函数的参数和数据类型时,我们需要根据实际需求进行选择和设置。
函数的代码块中,我们可以使用各种VBA的内置函数和特定的编程方法来实现所需的功能。
需要注意的是,函数定义完毕后,我们可以通过在其他地方调用函数名并传入参数来获取其返回的计算结果。
举例来说,我们可以编写一个加法函数Addition,来计算两个数相加的结果。
代码如下:```Function Addition(a As Double, b As Double) As DoubleAddition = a + bEnd Function```在这个例子中,我们定义了一个名为Addition的函数,它接受两个Double类型的参数a和b,并返回一个Double类型的结果。
函数的代码块中,我们将a和b相加的结果赋值给Addition,从而实现了加法计算。
要在其他地方调用这个函数,我们可以使用类似于以下的代码:result = Addition(5, 3)```通过将5和3作为参数传递给Addition函数,我们可以得到8作为结果。
快速学习VBA编程语言基础知识
快速学习VBA编程语言基础知识VBA(Visual Basic for Applications)是一种宏编程语言,是Microsoft Office套件中的一部分,通过使用VBA,用户可以自动化执行各种任务,增加工作效率。
本文将带你快速学习VBA编程语言的基础知识,包括VBA的概述、变量和数据类型、控制语句、函数和子程序等内容。
第一章:VBA的概述VBA是一种基于Visual Basic语言的宏编程语言,它可以用于编写自动化任务、自定义功能和处理数据。
VBA可以与Office套件中的各种应用程序(如Excel、Word和PowerPoint等)进行集成,使用户能够通过编程方式操作这些应用程序。
VBA的语法与VB语言非常相似,学习VBA可以帮助你更好地理解VB语言的工作原理。
第二章:变量和数据类型在VBA中,变量用于存储数据,数据类型定义了变量可以存储的数据种类。
VBA中常见的数据类型包括整型、浮点型、字符串型、布尔型和日期型等。
本章将详细介绍这些数据类型的特点和使用方法,并教你如何声明和初始化变量。
第三章:控制语句控制语句是VBA编程中用于决策和控制程序流程的关键工具。
本章将介绍VBA中的条件语句(如If语句和Select Case语句)和循环语句(如For循环和Do循环),并给出实际案例来说明它们的用法。
了解和掌握控制语句,可以使你的程序更加灵活和高效。
第四章:函数和子程序函数和子程序是一种封装代码的方式,可以重复使用,并且可以实现复杂的功能。
VBA内置了许多常用的函数(如字符串处理函数和数学函数等),同时也允许用户创建自定义函数和子程序。
本章将介绍如何使用VBA内置函数和如何创建自定义函数和子程序,通过实例帮助你理解其用法。
第五章:错误处理在编程过程中,错误是不可避免的。
VBA提供了一套完善的错误处理机制,可以帮助用户发现和处理程序中的错误。
本章将介绍错误处理的基本原则和常用的处理方法,例如使用On Error语句和Err对象来捕获和处理错误。
指令系统中各种助记符的英文全名
我现将指令系统中各种助记符的英文全名写出来,各种助记符的记忆就会变得很简单o(∩_∩)o...在这之前,先说一下寄存器:数据寄存器分为:AH&AL=AX(accumulator):累加寄存器,常用于运算;在乘除等指令中指定用来存放操作数,另外,所有的I/O指令都使用这一寄存器与外界设备传送数据.BH&BL=BX(base):基址寄存器,常用于地址索引;CH&CL=CX(count):计数寄存器,常用于计数;常用于保存计算值,如在移位指令,循环(loop)和串处理指令中用作隐含的计数器.DH&DL=DX(data):数据寄存器,常用于数据传递。
他们的特点是,这4个16位的寄存器可以分为高8位: AH, BH, CH, DH.以及低八位:AL,BL,CL,DL。
这2组8位寄存器可以分别寻址,并单独使用。
另一组是指针寄存器和变址寄存器,包括:SP(Stack Pointer):堆栈指针,与SS配合使用,可指向目前的堆栈位置;BP(Base Pointer):基址指针寄存器,可用作SS的一个相对基址位置;SI(Source Index):源变址寄存器可用来存放相对于DS段之源变址指针;DI(Destination Index):目的变址寄存器,可用来存放相对于 ES 段之目的变址指针。
指令指针IP(Instruction Pointer)标志寄存器FR(Flag Register)OF(overflow flag)DF(direction flag)CF(carrier flag)PF(parity flag)AF(auxiliary flag)ZF(zero flag)SF(sign flag)IF(interrupt flag)TF(trap flag)段寄存器(Segment Register)为了运用所有的内存空间,8086设定了四个段寄存器,专门用来保存段地址:CS(Code Segment):代码段寄存器;DS(Data Segment):数据段寄存器;SS(Stack Segment):堆栈段寄存器;ES(Extra Segment):附加段寄存器。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
南昌大学实验报告---(2)串处理与子程序学生姓名温帅学号:6100411001专业班级:电Ⅲ111班实验类型:■验证□综合□设计□创新实验日期:2012/11/14,2012/11/21实验成绩:一、实验目的1.掌握汇编语言堆栈传递参数的子程序调用方法,主程序与子程序之间的调用关系及调用方法,熟悉串操作指令的功能与应用;2.分析和理解高级语言(C++)中函数调用参数传递方法,掌握子程序调用过程中近程调用与远程调用的区别;3.掌握高级语言(C++)与汇编语言的方法,串操作指令的寻址方式及使用方法,编写常用的字符串处理程序。
二、实验内容1.字符串统计。
从键盘最多输入80个字符存放在STR开始的存储区中,统计其中含有小写字母的个数,将统计结果以两位十进制数显示在屏幕上。
2.删除重复字符。
从键盘最多输入80个字符存放在STR开始的存储区中,删除其中重复的字符,输出删除处理后的字符串。
3.采用C++中嵌入汇编代码的方法实现用汇编代码计算C++中输入的两个整数之和并输出结果。
4.C++中调用汇编程序,该汇编程序实现在数组中查找某个数,如果找到,C++程序中输出”Found!”,否则输出”Not found!”。
5.将BUF开始的10个单元中的二进制数转换成两位十六进制数的ASCII 码,在屏幕上显示出来。
要求码型转换通过子程序HEXAC实现,在转换过程中,通过子程序DISP实现显示。
6.编写一个主程序,从键盘接收若干个字符,然后用远调用的方法,调用子程序统计字符串中字符’b’的个数.子程序的参数是字符串的首地址TABLE,字符串长度N及字符”b”.子程序返回字符"b”的个数.参数传送采用堆栈实现.主程序在子程序返回后,显示字符”b”及其个数(设为一位十六进制数)。
三. 实验要求1.认真预习有关串操作的指令极其寻址方式的特点,能够正确使用串操作指令,并准备好数据。
2.依题意分析给出程序设计算法。
四.实验环境PC微机DOS操作系统或Windows 操作系统MASM.EXE,LINK.EXE,或宏汇编集成环境RADASM 五.实验步骤1.用1号系统调用从键盘键入一个字符串,然后统计其中小写字母的个数。
程序每次执行,都能得到不同的结果。
2.要求编写一个在同一个字符串中删除字符,并将其余字符向前递补的程序。
六.实验报告要求1、对照参考程序,画出程序流程图。
2、总结字符串处理的编程方法,提出改进和完善此类程序的设计方案。
七.思考题1.如果要求以INT 21H的10号功能调用来实现字符串的输入,请修改程序;解:把AGAIN: MOV AH, 1 MOV STR,78INT 21H LEA DX,STRCMP AL,0DHJZ DONE INT 21HMOV [DI],AL MOV CL,STR+1INC DIINC CLJMP AGAIN2.如果要统计输入的数字字符个数,指出程序修改的地方;解:(1)在数据段中定义一个FIGURE DB 0NEXT : CMP AL,'0'(2)把JL NXET1NEXT: LOOP CYCLE CMP AL,'9'JG NXET1INC FIGURENXET 1;LOOP CYCLE(3) 在输出的时候加上一个FIGURE就行了。
3.如果输入的小写字母数小于10(如输入了8个小写字符,这时候参考程序会输出小写字母个数是08)时候,如何修改程序,使得输出小写字母只有一位数而不是两位(如输入小写字母个数为个时输出8而不是08)。
解:在MOV AL,BL 之前心比较BL大小CMP BL,9MOV AH,0 JLE LOOP1MOV CL,10 ..............DIV CL LOOP1:ADD BL,30HMOV BX,AX MOV DL,BLMOV AH,2INT 21H参考程序清单1.统计小写字母个数的程序清单:DATA SEGMENTMSG1 DB 'Input a string:',0AH,0DH,'$'MSG2 DB 'The number of lowercase letter is:$'STR DB 80 DUP(?)DATA ENDSCODE SEGMENTASSUME CS:CODE, DS:DATASTART: MOV AX, DATAMOV DS, AX;输出提示LEA DX,MSG1MOV AH,9INT 21HLEA DI, STRMOV CL, 0 ;CL用来记录输入字符数AGAIN: MOV AH, 1INT 21HCMP AL,0DHJZ DONE ; 输入回车键则转DONEMOV [DI],ALINC DIINC CLJMP AGAINDONE: LEA SI,STRMOV CH,0 ;CX保存输入字符数MOV BL,0 ;BL用来统计小写字符个数CLDCYCLE: LODSBCMP AL,'a'JB NEXTCMP AL,'z'JA NEXTINC BLNEXT: LOOP CYCLE;回车换行MOV AH,2MOV DL,0AHINT 21HMOV DL,0DHINT 21H;输出提示LEA DX,MSG2MOV AH,9INT 21H;以下显示输入小写字母个数的两位十进制数 MOV AL,BL ;小写字符个数送ALMOV AH,0 ;AX存放小写字符个数MOV CL,10DIV CL ;十位数在AL中,个位数在AH中 MOV BX,AX ;十位数在BL中,个位数在BH中MOV DL,BLMOV AH,2OR DL,30HINT 21H ;输出小写字母个数的十位数字MOV DL,BHOR DL,30HMOV AH,2INT 21H ;输出小写字母个数的个位数字MOV AH,4CHINT 21HCODE ENDSEND START2.删除字符串中重复字符的源程序清单:DATA SEGMENTSTR DB 80 DUP(?)LEN DW ?DATA ENDSCODE SEGMENTASSUME CS:CODE,DS:DATA,ES:DATASTART: MOV AX,DATAMOV DS,AXMOV ES,AX ;初始化数据段和附加段为同一段值 LEA SI,STR ;SI<=输入串的首地址;从键盘输入字符串MOV CL,0 ;CL用来存放输入字符数AGAIN: MOV AH,1INT 21HCMP AL,0DH ;回车结束输入JZ IN_DONEMOV [SI],ALINC SIINC CLJMP AGAININ_DONE: MOV CH,0 ;CX存放输入字符数MOV LEN,CX ;将输入字符数保存到LEN;将输入字符串中重复出现字符替换为0LEA SI,STR ;SI<=输入串的首地址MOV 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: ;将那些被替换成0的字符去掉LEA SI,STR ;SI<=输入串的首地址MOV CX,LENRPT: 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: ;回车换行MOV AH,2MOV DL,0AHINT 21HMOV AH,2MOV DL,0DHINT 21H;输出结果LEA SI,STR ;SI<=输入串的首地址MOV CX,LENMOV AH,2LOP: MOV DL,[SI]CMP DL,0JZ EXITINT 21HINC SILOOP LOPEXIT:MOV AH,4CHINT 21HCODE ENDSEND START串处理指令与子程序-------子程序一.实验目的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命令检查远程调用及近程调用时堆栈的变化。