注册 登录
编程论坛 汇编论坛

请教!从键盘输入字符串并输出该字符串(汇编程序—I/O功能调用)

hero2007 发布于 2007-03-22 17:52, 4733 次点击

以下是从键盘输入字符串并输出该字符串的简单汇编程序,我们老师的要求是将程序中的2号调用改成9号调用,本人还在思考中,有能解决此问题的请回复,谢谢!

如果我了解了该题答案,一定和大家共享

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

续一:

我们汇编老师的教学是先让我们看程序,写程序,再讲基本指令,基本结构……

学习汇编重要的是掌握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。

[此贴子已经被作者于2007-3-22 17:57:20编辑过]

13 回复
#2
lefttime2007-03-22 20:20
[QUOTE]
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
[/QUOTE]

#3
hero20072007-03-22 21:19
呵呵,解释的这么详细,受用啊!!
谢了!
不过,怎么将2号调用改为9号调用呢,这是我不知道的。

[此贴子已经被作者于2007-3-22 21:26:47编辑过]

#4
hero20072007-03-24 13:45


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

以上是将2号调用改为9号调用后的程序,我发现byte ptr mov bh,0都可以去掉,程序可以正常运行。
此程序将原程序中的MOV CL,BUF+1 改为MOV BL,BUF+1 这两个有什么区别,分别实现的是什么操作呢?

mov byte ptr[si+bx],'$'
mov DX,si
是什么操作?

#5
lefttime2007-03-24 19:25
MOV BL,BUF+1 ;这句和你那下一句连起来看
......
mov byte ptr[si+bx],'$' ;这是因为输出的字符串要以 $ 符号结尾,不然输出就有可能不只是原串
mov DX,si
#6
hero20072007-03-24 21:36

你说的我明白啊!

我想知道以下程序段是对CPU实现的什么操作。
mov bl,BUF+1
mov bh,0
lea si,BUF+2
mov byte ptr[si+bx],'$'
mov DX,si
MOV AH,9

#7
lefttime2007-03-25 16:49

输出以si为地址开始位置到以'$'为结束之间的字符

#8
I喜欢c2007-03-25 23:04
DEC CL
JNZ NEXT;此处输入代码段代码

为何不用 loop NEXTV...
#9
wangsong02152007-05-14 22:26
二进制转换成十进制数的算法原理谁能解释一下,好像跟转换成十六进制和八进制有所不同
#10
hero20072007-05-14 23:09
以下是引用I喜欢c在2007-3-25 23:04:12的发言:
DEC CL
JNZ NEXT;此处输入代码段代码

为何不用 loop NEXTV...

当然可以,只是LOOP才学不久。

#11
hero20072007-05-14 23:13
现在回头看,终于可以理解了。
mov bl,BUF+1 ;BUF+1里装的是输入字符的个数
mov bh,0 ;为避免BH不为零影响BX的值,先清零
lea si,BUF+2 ;将BUF+2地址给SI
mov byte ptr[si+bx],'$';从BUF+2开始输出输入的字符,遇'$'结束
mov DX,si ;相当于将SI地址给DX,准备输出
MOV AH,9 ;DOS9号调用
INT 21H ;结束

[此贴子已经被作者于2007-5-14 23:17:43编辑过]

#12
觉雨2007-05-17 09:01
呵呵!!!!嘿嘿~~~
#13
earthworm2007-06-13 10:32
回复:(hero2007)请教!从键盘输入字符串并输出该字...
CRLF DB 0AH,0DH,"$";此处输入数据段代码
-----------这一句就开始不懂了…………
#14
菜鸟上路2007-06-13 12:21
以下是引用earthworm在2007-6-13 10:32:06的发言:
CRLF DB 0AH,0DH,"$";此处输入数据段代码
-----------这一句就开始不懂了…………

那就没办法了

1