字符串必须以"$"结尾,并且必须在数据段上面提前定义好
- 过程:
- 使用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换换个顺序,会发现程序无法实现原来的需求。
1 条评论
[…] 汇编(10)字符串输出/AH 9/LEA指令 […]