从键盘输入字符串并输出该字符串(汇编程序)
- 格式:doc
- 大小:21.50 KB
- 文档页数:7
用汇编语言编写的以空格为前导输出字符串程序实验内容:有些字符串以零作为前导,现要求以空格作为前导设计目的:1.进一步熟悉程序设计的思路和方法2.掌握各类程序的设计技巧设计原理:有些字符串以零作为前导,现在将空格作为前导。
字符串的显示是按地址顺序输出的,将零换作空格,只需要先输出一个空格字符,将字符空格的地址放在字符串首地址+1位置,然后按顺序逐个输出即可。
扩展适用:使用范围广泛,用于改写字符串,在编程中有较多的。
参看流程图:附录A:;程序模板SSEG SEGMENT PARA STACK 'stack'dw 100h dup(0) ;初始化堆栈大小为100SSEG ENDSDSEG SEGMENTBUF DB '0ABCD$';设计原字符串为0ABCDESEG SEGMENT;附加段:在此处添加程序所需的数据ESEG ENDSCSEG SEGMENTassume cs:CSEG, ds:DSEG, es:ESEG, ss:SSEGMAIN PROC FAR ;主程序入口mov ax, dsegmov ds, axmov ax,esegmov es, axLEA SI,BUFMOV DL,' 'MOV AH,02INT 21HINC SIMOV DX,SIMOV AH,09INT 21H;按任意键退出mov ah,1int 21hmov ax, 4c00h ;程序结束,返回到操作系统系统int 21hMAIN ENDPCSEG ENDSEND MAIN运行结果:附录B:参考文献:《微机原理与接口技术》结束语:变成过程中,感悟很多,虽然实验内容简单,但在编程的应用中会有狠广泛的使用,自己的编程思路得到了巩固,在以后的学习路上我会继续积累学习经验,每次编程都是学习的积累。
汇编语言实验7实验报告一、实验目的本次实验旨在通过汇编语言编写程序,实现对字符串的操作和输出。
二、实验内容1. 编写一个汇编程序,要求从键盘输入一个字符串,并将其逆序输出到屏幕上;2. 编写一个汇编程序,要求从键盘输入两个字符串,并将它们拼接起来后输出到屏幕上。
三、实验过程1. 字符串逆序输出程序首先,需要从键盘输入一个字符串。
为了方便起见,我们可以先规定字符串的最大长度为100。
接着,我们需要定义两个变量:```buffer db 100 ; 用于存储输入的字符串length dw ? ; 存储输入的字符串长度```其中,db代表定义字节型变量,dw代表定义双字节型变量。
然后,我们需要使用INT 21H中断来读取用户输入的字符串。
具体而言,我们可以使用下面这段代码:```mov ah, 0Ah ; 设置INT 21H功能号为0Ahmov dx, offset buffer ; 将buffer的地址传给DX寄存器int 21h ; 调用INT 21H中断```该代码会将用户输入的字符串存储在buffer中,并且将其长度存储在length变量中。
接着,我们需要将该字符串逆序输出到屏幕上。
为了实现这个功能,我们可以使用栈来存储字符串中的每个字符,并逐个弹出来输出。
具体而言,我们可以使用下面这段代码:```mov si, offset buffer + 1 ; 将si寄存器指向字符串的第一个字符mov cx, length ; 将cx寄存器设置为字符串长度dec cx ; 字符串长度需要减1reverse:push byte ptr [si] ; 将当前字符压入栈中inc si ; 指向下一个字符loop reverse ; 循环直到所有字符都被压入栈中mov ah, 02h ; 设置INT 21H功能号为02h,表示输出一个字符print:pop dx ; 弹出栈顶元素int 21h ; 输出该字符loop print ; 循环直到所有字符都被弹出并输出完毕```2. 字符串拼接程序首先,需要从键盘输入两个字符串。
汇编语言---字符串操作指令汇编语言---字符串操作指令字符串操作指令的实质是对一片连续的存储单元进行处理,这片连续的存储单元由隐含指针DS:SI或ES:DI来指定;字符串操作指令可对内存单元按照字节、字、双字进行处理,并能根据操作对象的字节数使变址寄存器SI/DI增加或减少1、2、4字节;规定如下:A.当DF=0时,变址寄存器SI/DI增加1、2、4字节;即:变址寄存器SI/DI递增的步长可以是1、2、4字节;B.当DF=1时,变址寄存器SI/DI减少1、2、4字节;即:变址寄存器SI/DI递减的步长可以是1、2、4字节;一、取字符串数据指令(Load String Instruction)从指针DI:SI所指定的内存单元开始,取一个字节/字/双字,然后存入到AL/AX/EAX中,并根据标志位DF的值对寄存器SI 做相应的增减;把存放字符串数据的连续存储区当做是数据源,使用寄存器SI;该指令的执行不会影响任何标志位;指令格式: LODS 地址表达式LODSB/LODSW 地址表达式LODS 地址表达式;80386+在指令LODS中,它会根据"地址表达式"的属性来决定读取一个字节、字或双字;即:当该地址表达式的属性为字节、字或双字时,将从指针DI:SI处读取一个字节到AL中,或读取一个字到AX中,或读取一个双字到EAX中,与此同时,SI还将分别增减1、2、4字节;取字符串数据指令的功能示意图如下图所示:二、置字符串数据指令(Store String Instruction)该指令把寄存器AL/AX/EAX中的值存入指针ES:DI所指向内存单元开始的一片存储单元中,并根据标志位DF的值对寄存器DI做相应的增减;把存放字符串的连续存储区当做是数据的目的地,使用寄存器DI;该指令的执行并不会影响任何标志位;指令格式: STOS 地址表达式STOSB/STOSW 地址表达式STOSD 地址表达式;80386+置字符串数据指令的功能示意图如下图所示:三、字符串传送指令(Move String Instruction)该指令把指针DS:SI所指向的字节、字或双字传送给指针ES:DI所指向的内存单元,并根据标志位DF的值对寄存器DI 和SI分别作相应的增减;该指令的执行并不会影响任何标志位;指令格式: MOVS 地址表达式1,地址表达式2MOVSB/MOVSW 地址表达式1,地址表达式2MOVSD 地址表达式1,地址表达式2 ;80386+字符串传送指令的功能示意图如下图所示:四、输入字符串指令(Input String Instruction)该指令是从某一指定端口接受一个字符串,并存入到一片连续的存储单元中;输入端口由寄存器DX指定,存储单元的首地址由指针ES:DI 来确定,读入的数据个数由寄存器CX来确定;在指令的执行过程中,还要根据标志位DF的值来对寄存器DI做相应的增减;把存放字符串的连续存储区当做是数据的目的地;该指令不会影响任何标志位;与指令有关的操作数ES、DI、DX和CX等都是隐含操作数; 指令格式: INS 地址表达式INSB/INSW 地址表达式INSD 地址表达式;80386+五、字符串输出指令(Output String Instruction)该指令是把一个给定的字符串输出到一个指定的端口中;输出端口由通用寄存器DX指定,输出数据的首地址由指针DS:SI确定,输出数据的个数由计数寄存器CX来确定;在指令执行的过程中,还要根据方向标志DF的值来对变址寄存器SI 做相应的增减;该指令的执行并不会影响任何标志位;与指令有关的操作数DS、SI、DX和CX等都是隐含操作数; 指令格式: OUTS 地址表达式OUTSB/OUTSW 地址表达式OUTSD 地址表达式;80386+六、字符串比较指令(Compare String Instruction)该指令是把指针DS:SI所指向的字节、字、双字的值与指针ES:DI 所指向的字节、字、双字的值相减,并用所得到的差来设置相关标志位;与此同时,变址寄存器SI和DI也将根据方向标志位DF的值做相应的增减;指令格式: CMPS 地址表达式1,地址表达式2CMPSB/CMPSW 地址表达式1,地址表达式2CMPSD 地址表达式1,地址表达式2 ;80386+受影响的标志位: AF,CF,OF,PF,SF,ZF字符串比较指令的功能示意图如下图所示:七、字符串扫描指令(Scan String Instruction)该指令是用指针ES:DI所指向字节/字/双字的值与相应的AL/AX/EAX的值相减,并依据所得到的差值来设置相关标志位;与此同时,变址寄存器DI还将根据方向标志DF的值来做相应的增减;指令格式: SCAS 地址表达式SCASB/SCASW 地址表达式SCASD 地址表达式;80386+受影响的标志位: AF,CF,OF,PF,SF,ZF字符串扫描指令的功能示意图如下图所示:八、重复字符串操作指令(Repeat String Instruction)前面的字符串操作指令:取字符串数据、置字符串数据、字符串传送、输入字符串、输出字符串、字符串比较、字符串扫描,等指令,都是执行一次所具有的功能;但是,每个字符串通常都是由多个字符组成的,所以,需要重复执行这些字符串操作指令;为了满足这种需要,指令系统提供了一组重复前缀指令;虽然在这些字符串指令的前面都可以添加一个重复前缀指令,但是由于指令执行结果的差异,对某个具体的字符串指令又不用重复前缀指令而改用其它循环来实现重复的需要;重复字符串操作指令对标志位的影响是由被重复的字符串操作指令来决定;1.重复前缀指令REP(Repeat String Instruction) 重复前缀指令是重复其后指定的字符串操作指令,重复的次数由计数寄存器CX来决定;指令格式:REP LODS/LODSB/LODSW/LODSDREP STOS/STOSB/STOSW/STOSDREP MOVS/MOVSB/MOVSW/MOVSDREP INS/INSB/INSW/INSDREP OUTS/OUTSB/OUTSW/OUTSD重复前缀指令的执行步骤如下:STEP1:判断: CX=0STEP2:如果CX=0,则结束重复操作,执行程序中的下一条指令;STEP3:否则,CX=CX-1(不影响相关标志位),并执行重复前缀指令后面指定的字符串操作指令,在该指令执行完后,再转到步骤STEP1;从上面的重复前缀指令格式来看,虽然我们可以使用重复前缀指令来重复取字符串数据指令(第一组指令),但是可能会因为指令的执行结果而在程序中几乎不会使用;例如:编写一段程序,计算字符串"12345abcdefg"中各个字符的ASCII之和;解:......MESS DB '12345abcdefg' ;在数据段进行变量说明......MOV AX,SEG MESSMOV DS,AXLEA SI,MESS ;用DS:SI来指向字符串的首地址;MOV CX,13D ;重复次数XOR BX,BX ;置求和的初值为0REP LODSB ;循环去处字符; ......从程序片段中看,虽然"REP LODSB"能从字符串中逐一取出每个字符,但这个操作是在同一条指令中完成的,程序的其它指令根本无法处理每次取出的字符数据,指令的执行结果是:AL中只保存了最后一次取出的字符'h'的ASCII码;所以,为了实现本例的要求,不能使用重复前缀指令,而要把指令"REP LODSB"改写成如下四条指令:XOR AH,AH ;为后面的累加做准备AGAIN:LODSBADD BX,AX ;AL是被取出的字符,AH已被清0LOOP AGAIN2.条件重复前缀指令(Repeat String Conditionally) 条件重复前缀指令与重复前缀指令的功能相似,所不同的是:条件重复前缀指令中的重复次数不仅由CX来决定,而且还会由标志位ZF的值来决定;根据ZF所起的作用又可分为两种:相等重复前缀指令和不等重复前缀指令;A.相等重复前缀指令:指令格式:REPE/REPZ SCAS/SCASB/SCASW/SCASDREPE/REPZ CMPS/CMPSB/CMPSW/CMPSD该重复前缀指令的执行步骤如下:STEP1:判断条件: CX!=0 且ZF=1STEP2:如果条件不成立,则结束重复操作,执行程序中的下一条指令;STEP3:否则,CX=CX-1(不影响任何标志位),并执行重复前缀指令后面指定的字符串操作指令,在该指令执行后,再转到步骤STEP1;B.不等重复前缀指令:指令格式:REPNE/REPNZ SCAS/SCASB/SCASW/SCASDREPNE/REPNZ CMPS/CMPSB/CMPSW/CMPSD该重复前缀指令的执行步骤如下:STEP1:判断条件:CX!=0 且ZF=0STEP2:如果条件不成立,则结束重复操作,执行程序中的下一条指令;STEP3:否则,CX=CX-1(不影响任何标志位),并执行重复前缀指令后面指定的字符串操作指令,在该指令执行完后,再转到步骤STEP1;。
本科实验报告实验名称:子程序设计实验实验五子程序设计实验(设计性实验)一、实验要求和目的1.熟悉汇编语言程序设计结构;2.熟悉汇编语言子程序设计方法;3.熟悉利用汇编语言子程序参数传递方法;4.熟悉汇编语言字符串处理基本指令的使用方法;5.掌握利用汇编语言实现字符串的输入输出程序设计方法;6.掌握数制转换程序实现方法。
二、软硬件环境1、硬件环境:计算机系统windows;2、软件环境:装有MASM、DEBUG、LINK、等应用程序。
三、实验涉及的主要知识A)子程序知识要点:1、掌握子程序的定义语句;过程名PROC [near/far] 过程体RET过程名ENDP2.子程序结构形式一个完整的子程序一般应包含下列内容:1. )子程序的说明部分在设计了程序时,要建立子程序的文档说明,使用户能清楚此子程序的功能和调用方法.说明时,应含如下内容:.子程序名:命名时要名中见意..子程序的功能:说明子程序完成的任务;.子程序入口参数:说明子程序运行所需参数及存放位置;.子程序出口参数:说明子程序运行结果的参数及存放位置;.子程序所占用的寄存器和工作单元;.子程序调用示例;2、)掌握子程序的调用与返回在汇编语言中,子程序的调用用CALL,返回用RET指令来完成。
.段内调用与返回:调用子程序指令与子程序同在一个段内。
因此只修改IP;.段间调用与返回:调用子程序与子程序分别在不同的段,因此在返回时,需同时修改CS:IP。
3.)子程序的现场保护与恢复保护现场:在子程序设计时,CPU内部寄存器内容的保护和恢复。
一般利用堆栈实现现场保护和恢复的格式:过程名PROC[NEAR/FAR]PUSH AXPUSH BX..PUSH DX...POP DX...POP AXRET过程名ENDP4.子程序的参数传递方法1.寄存器传递参数这种方式是最基本的参数传递方式。
2.存储器单元传(变量)递参数这种方法是在主程序调用子程序前,将入口参数存放到约定的存储单元中;子程序运行时到约定存储位置读取参数;子程序执行结束后将结果也放在约定存储单元中。
从键盘输入字符串并输出该字符串(汇编程序) DATAS SEGMENTSTR DB"please input a string:$"BUF DB 20DB ?DB 20 DUP (?)CRLF DB 0AH,0DH,"$";此处输入数据段代码DATAS ENDSSTACKS SEGMENT STACKDB 200 DUP(?) ;此处输入堆栈段代码STACKS ENDSCODES SEGMENTASSUME CS:CODES,DS:DATAS,SS:STACKSSTART: MOV AX,DATASMOV DS,AXLEA DX,STRMOV AH,9INT 21HMOV AH,10LEA DX,BUFINT 21HLEA DX,CRLFMOV AH,9INT 21HMOV CL,BUF+1LEA SI,BUF+2NEXT: MOV DL,[SI]MOV AH,2INT 21HINC SIDEC CLJNZ NEXT;此处输入代码段代码MOV AH,4CHINT 21HCODES ENDSEND START以上是从键盘输入字符串并输出该字符串的简单汇编程序,我们老师的要求是将程序中的2号调用改成9号调用,本人还在思考中,有能解决此问题的请回复,谢谢!如果我了解了该题答案,一定和大家共享。
续一:我们汇编老师的教学是先让我们看程序,写程序,再讲基本指令,基本结构……学习汇编重要的是掌握CPU结构、程序结构以及熟练的掌握7种指令的运用。
以下是本人整理的对上面程序的部分解释:BUF:键盘缓冲区BUF。
DB:定义变量的类型为字节类型。
DB 20:表示缓冲区能容纳20个字符。
DB 200 DUP(?)中的问号:不对分配的存储单元初始化。
DS:存放当前数据段的段地址。
CS:存放当前代码段的段地址。
SS:存放当前堆栈段的段地址。
MOV:传送指令。
AX:存放接收到的数据或发送数据。
《微机原理及接口技术》复习总结综合版——简答题第一篇:《微机原理及接口技术》复习总结综合版——简答题综合版—简答题欢迎使用KNKJ2012DXZY系统《微机原理及接口技术》学科复习综合版—简答题1、微型计算机由那些基本功能部件组成?微处理器、主存储器、系统总线、辅助存储器、输入/输出(I/O)接口和输入/输出设备2、什么是(计算机)总线?在计算机中,连接CPU与各个功能部件之间的一组公共线路,称为总线3、微型计算机系统的基本组成?微型计算机,系统软件,应用软件,输入输出设备4、简述冯.诺依曼型计算机基本组成。
冯.诺依曼型计算机是由运算器,控制器,存储器,输入设备和输出设备组成的。
其中,运算器是对信息进行加工和运算的部件;控制器是整个计算机的控制中心,所以数值计算和信息的输入,输出都有是在控制器的统一指挥下进行的;存储器是用来存放数据和程序的部件,它由许多存储单元组成,每一个存储单元可以存放一个字节;输入设备是把人们编写好的程序和数据送入到计算机内部;输出设备是把运算结果告知用户。
5、什么是机器数?什么是机器数的真值?数在机器内的表示形式为机器数。
而机器数对应的数值称为机器数的真值。
6、8086与8088这两个微处理器在结构上有何相同点,有何主要区别?相同点:(1)内部均由EU、BIU两大部分组成,结构基本相同。
(2)用户编程使用的寄存器等功能部件均为16位。
(3)内部数据通路为16位。
区别 :(1)对外数据总线8086:16位,8088:8位。
(2)指令队列8086:6级,8088:4级。
7、8086CPU内部由哪两部分组成?各完成什么工作?在8086内部由BIU和EU两大部分组成,BIU主要负责和总线打交道,用于CPU与存储器和I/O接口之间进行数据交换;EU主要是将从指令队列中取得的指令加以执行。
8、简述8086内部分为EU和BIU两大功能的意义。
这两部分分开可以在执行指令的同时,从存储器中将将要执行的指令取到指令队列,使两部分并行工作,提高CPU的速度。
C语言程序设计教程第一章练习题题目(精选5篇)第一篇:C语言程序设计教程第一章练习题题目单选题1、下列语言中不属于计算机语言的三大类的是(C)。
A.机器语言 B.汇编语言 C.脚本语言 D.高级语言2、下列说法中不正确的是(C)A.计算机语言大致可分为三大类,即机器语言、汇编语言和高级语言B.C语言是一种通用的、过程式的编程语言,具有高效、灵活、可移植等优点C.C语言属于汇编语言D.高级语言比汇编语言更贴近于人类使用的语言,易于理解、记忆和使用3、以下开发工具中不属于主流的开发工具的是(B)A.Visual Studio B.Xcode C.Code::Block D.Eclipse4、下列选项是对主流开发工具的介绍,其中错误的是(B)A.Visual Studio支持C/C++、C#、F#、VB等多种程序语言的开发和测试B.Code::Block是一个免费的跨平台IDE,支持C、C++和Fortan程序的开发C.Eclipse是一种被广泛使用的免费跨平台IDE,最初由IBM公司开发D.Vim是一款功能非常强大的IDE(和其他IDE不同的是,Vim本身并不是一个用于开发计算机程序的IDE,而是一款功能非常强大的文本编辑器,它是UNIX系统上Vi编辑器的升级版。
)5、下列选项中,不属于开发一个C语言应用程序的具体实现步骤的是(A)A.启动开发工具 B.添加源文件 C.编写代码 D.运行程序6、下列选项中,关于main()函数叙述不正确的是(C)A.一个完整的C语言程序中,有且只能有一个main()函数B.main()函数是程序的主入口,程序总是从main()函数开始执行C.如果没有声明main()函数,程序将从第1行开始执行D.main()函数可以有返回值,也可以没有返回值7、下面程序中,合法的选项是(D)A.#includeint main(){ printf(“hello worldn”);return 0;}B.#includeint man(){ printf(“hello worldn”);return 0;}C.#includeint main(){ printf(“hello worldn”)return 0;}D.#includeint main(){ print(“hello worldn”);return 0;}8、下面程序中,运行结果为“1,2”的是(A)A.#includeint main(){ int a = 1;int b = 2;printf(“%d %dn”,a,b);return 0;}B.#includeint main(){ int a = 1;int b = 2;printf(“%d,”a);printf(“%dn”,b);return 0;}C.#includeint main(){ int a = 1, b = 2;printf(“%d,%dn”,a,b);return 0;}D.#includeint main(){ int a = 1,a= b = 2;printf(“%d,%dn”,a,b);return 0;}9、下列关于注释的描述中,错误的是(B)A.C语言中的注释有两种类型:单行注释和多行注释B.所有的注释都可以嵌套使用C.单行注释用“//”符号表示,“//”后面为被注释的内容D.多行注释以符号“/*”开头,以符号“*/”结尾解析:在C语言中,有的注释可以嵌套使用,有的则不可以,例如:多行注释“/*…*/”中可以嵌套单行注释“//”;多行注释“/*…*/”中不能嵌套多行注释“/*…*/”。
从键盘输入字符串并输出该字符串(汇编程序)
DATAS SEGMENT
STR DB"please input a string:$"
BUF DB 20
DB ?
DB 20 DUP (?)
CRLF DB 0AH,0DH,"$";此处输入数据段代码
DATAS ENDS
STACKS SEGMENT STACK
DB 200 DUP(?) ;此处输入堆栈段代码
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START: MOV AX,DATAS
MOV DS,AX
LEA DX,STR
MOV AH,9
INT 21H
MOV AH,10
LEA DX,BUF
INT 21H
LEA DX,CRLF
MOV AH,9
INT 21H
MOV CL,BUF+1
LEA SI,BUF+2
NEXT: MOV DL,[SI]
MOV AH,2
INT 21H
INC SI
DEC CL
JNZ NEXT;此处输入代码段代码
MOV AH,4CH
INT 21H
CODES ENDS
END START
以上是从键盘输入字符串并输出该字符串的简单汇编程序,我们老师的要求是将程序中的2号调用改成9号调用,本人还在思考中,有能解决此问题的请回复,谢谢!
如果我了解了该题答案,一定和大家共享。
续一:
我们汇编老师的教学是先让我们看程序,写程序,再讲基本指令,基本结构……
学习汇编重要的是掌握CPU结构、程序结构以及熟练的掌握7种指令的运用。
以下是本人整理的对上面程序的部分解释:
BUF:键盘缓冲区BUF。
DB:定义变量的类型为字节类型。
DB 20:表示缓冲区能容纳20个字符。
DB 200 DUP(?)中的问号:不对分配的存储单元初始化。
DS:存放当前数据段的段地址。
CS:存放当前代码段的段地址。
SS:存放当前堆栈段的段地址。
MOV:传送指令。
AX:存放接收到的数据或发送数据。
DX:使用间接寻址时存放端口地址。
LEA:取偏移地址。
CL:在移位指令和循环移动指令中,存放移位次数或者循环移位次数。
SI:在存储器寻址时,作为变址寄存器。
在串操作中,作为源串指针。
DEC:decrement。
INC:increment。
INT:interruput。
DATAS SEGMENT
STR DB"please input a string:$"
BUF DB 20 ;这里的20为指定存放字符的个数(理论上的) DB ? ;这的?可变,实际存放字符的个数(系统自动计算)
DB 20 DUP (?) ;这里的20是你在数据段开辟的空
间
CRLF DB 0AH,0DH,"$";回车换行;此处输入数据段代码
DATAS ENDS
STACKS SEGMENT STACK
DB 200 DUP(?) ;此处输入堆栈段代码
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START: MOV AX,DATAS
MOV DS,AX
LEA DX,STR ;9号中断前提,给参数DX赋值,指定输出字符串所在的有效地址
MOV AH,9
INT 21H
MOV AH,10 ;10号中断,接收输入字符串,此时DX为存放字符串的有效地址
LEA DX,BUF
INT 21H
LEA DX,CRLF
MOV AH,9
INT 21H
MOV CL,BUF+1 ;获取字符串中字符的个数
LEA SI,BUF+2 ;间接寻址
NEXT: MOV DL,[SI]
MOV AH,2 ;2号中断输出单个字符
INT 21H
INC SI ;输出一个地址往后加1
DEC CL ;顺便减少输出的次数
JNZ NEXT ;此处输入代码段代码
MOV AH,4CH
INT 21H
CODES ENDS
END START
2号调用是逐个显示字符,9号调用是一次完成字符串的显示,但结尾得加上'$'。
最上面程序中用的2号调用,使用循环输出字符串。
要将2号调用改为9号调用,必须改程序中的循环结构为顺序结构。
很明显,程序中的
NEXT:
INC SI
DEC CL
JNZ NEXT
都要去掉。
所以问题简化为改
MOV DL,[SI]
MOV AH,2
部分为9号调用,以及在9号调用后加上'$'。
续last:
以下是在编程爱好者论坛上请教别人加上自己的整理得出的答案,并非最简。
DATAS SEGMENT
STR DB 'please input a string:$'
BUF DB 20
DB ?
DB 20 DUP (?)
CRLF DB 0AH,0DH,"$"
;此处输入数据段代码
DATAS ENDS
STACKS SEGMENT STACK
DB 200 DUP(?) ;此处输入堆栈段代码
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START: MOV AX,DATAS
MOV DS,AX
LEA DX,STR
MOV AH,9
INT 21H
MOV AH,10
LEA DX,BUF
INT 21H
LEA DX,CRLF
MOV AH,9
INT 21H
;开始改的部分
mov bl,BUF+1 ;输出这里开始
mov bh,0 ;
lea si,BUF+2 ;首地址
mov byte ptr[si+bx],'$';结尾得加上 '$'
mov DX,si ;
MOV AH,9 ;
INT 21H ;结束
MOV AH,4CH
INT 21H
CODES ENDS
END START
我和同学交流之后发现,程序中mov byte ptr[si+bx],'$'可以改为mov [si+bx],'$' ,mov bh,0也可以去掉,这样就得出最简答案了。
终结:
DATAS SEGMENT
STR DB 'Please input a string:$'
BUF DB 20
DB ?
DB 20 DUP(24H)
CRLF DB 0AH,0DH,'$'
DATAS ENDS
DB 200 DUP(?)
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
MOV AX,DATAS
MOV DS,AX
LEA DX,STR
MOV AH,9
INT 21H
MOV AH,10
LEA DX,BUF
INT 21H
LEA DX,CRLF
MOV AH,9
INT 21H
LEA DX,BUF+2
MOV AH,9
INT 21H
MOV AH,4CH
INT 21H
CODES ENDS
END START
现在已经真正理解DOS10号以及9号功能调用了,今天再次看这个题目又得到一个答案:
DATAS SEGMENT
STR DB 'Please input a string:$'
BUF DB 20
DB ?
DB 20 DUP(?)
CRLF DB 0AH,0DH,'$'
DATAS ENDS
DB 200 DUP(?)
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS START:
MOV AX,DATAS
MOV DS,AX
LEA DX,STR
MOV AH,9
INT 21H
MOV AH,10
LEA DX,BUF
INT 21H
LEA DX,CRLF
MOV AH,9
INT 21H
MOV AL,BUF+1
ADD AL,2
MOV AH,0
MOV SI,AX
MOV BUF[SI],24H
LEA DX,BUF+2
MOV AH,9
INT 21H
MOV AH,4CH
INT 21H
CODES ENDS
END START。