字符串必须以"$"结尾,并且必须在数据段上面提前定义

  • 过程
  • 使用AH 9(见上一篇DOS系统功能的表)
  • 将要输出的字符串的位移地址保存到DX里面
  • 执行INT命令

代码示例:

MOV	AH,9	;将功能号设置为9,作用是显示字符串
LEA	DX,name	;把字符串的偏移地址存储到DX里,name换成字符串的名字
INT	21H	;输出字符串




LEA指令:取有效地址,也就是偏移地址。取源操作数地址的偏移量,并把它传送到目标操作数所在的单元。简单的说就是可以把一个东东的内存地址赋值给另外一个东东

使用方法:LEA 目标操作数源操作数

例:

LEA	DX,MSG	;取MSG的偏移地址,保存到DX里面







看个例子:

.MODEL SMALL	;内存模式small
.STACK 100H	;堆栈大小100H
.DATA		;数据段开始
ERR_MSG	DB	'ERROR!START AGAIN$'	;定义一个数据段类型为DB的ERR_MSG
.CODE		;代码段开始
MAIN	PROC
	MOV	AX,@DATA	
	MOV	DS,AX
;把DATA的首地址传送到AX再传送到DS里面,因为DS是数据段寄存器。不可以直接被赋值所以需要AX来中转
;不能对段寄存器直接给值(立即数)
;为了告诉DS数据存放在哪里,之后DS会自动到那个地方去取
;DS:数据段段地址寄存器,存放要访问数据的段地址。
	MOV	AH,9
	LEA	DX,ERR_MSG
	INT	21H
;功能号为9,代表显示字符串,取ERR_MSG的偏移地址到DX,输出
	MOV	AH,4CH
	INT	21H
;结束程序
MAIN	ENDP
	END	MAIN

  • 第7-9行:
  • 把DATA的首地址传送到AX再传送到DS里面,因为DS是数据段寄存器。不可以直接被赋值所以需要AX来中转
  • 不能对段寄存器直接给值(立即数)
  • 为了告诉DS数据存放在哪里,之后DS会自动到那个地方去取
  • DS:数据段段地址寄存器,存放要访问数据的段地址。




再看个例子:

.MODEL SMALL
.STACK 100H
.DATA	;定义数据段
IN_MSG DB 'Input Character:$'
Out_MSG DB 0DH,0AH,'Output Character:'	
CharData DB ?,'$'	
;定义字符串

.CODE
MAIN	PROC

	MOV	AX,@DATA
	MOV	DS,AX
;给DS存放DATA的首地址



	MOV	AH,9	;功能号9,显示字符串
	LEA	DX,IN_MSG	;取IN_MSG的偏移地址到DX
	INT	21H	;输出Input Character


	MOV	AH,1
	INT	21H	;功能号1,键盘输入并回显


	MOV	CharData,AL	;把用户输入的内容存储到CharData,

	MOV	AH,9	;功能号9,显示字符串
	LEA	DX,OUT_MSG	;取OUT_MSG的偏移地址到DX
	INT	21H	;输出


	MOV	AH,4CH	
	INT	21H	;终止程序
MAIN	ENDP
	END	MAIN

关于代码的第4-6行,我刚看到这个程序的时候觉得很奇怪,因为之前有提到过,字符串必须以$结尾,为什么在这里第五行并没有以$结尾呢为什么感觉后面的代码没有输出CharData的功能 为什么还是输出了呢

是因为输出字符串这个功能,是以$结束的,也就是说 当遇到$的时候输出结束。数据段的这一块虽然定义了三个但是可以看成一个整体,当第29行到第31行执行输出字符串Out_MSG的时候,实际上它是先输出的Out_MSG的内容然后继续往下面读CharData(之前用户输入的内容已经存储到这里了),然后遇到$结束读取。

其实不难理解,如果你把代码的第6行和第5换换个顺序,会发现程序无法实现原来的需求。

最后修改:2022 年 03 月 08 日
如果觉得我的文章对你有用,请随意赞赏