DOS中断INT 21h/AH=9h不需要字符值来打印,而是需要指向以$
结尾的字符串的内存偏移量来打印。
DOS 1+ - 将字符串写入标准输出
AH = 09h
DS:DX -> '$'-结尾的字符串
返回值:
AL = 24h ('$'终止字符串,尽管官方文档说明没有返回任何值)(至少在DOS 2.1-7.0和NWDOS上)
如果要使用INT 21h/AH=9h打印单个字符,则需要将该值移动到以$
符号结尾的缓冲区中。然后将该缓冲区的地址传递给INT 21h/AH=9h。根据您的第二个示例,以下内容应该可以工作:
.model tiny
.code
org 100h
main proc
mov ah, 09h ; DOS Interrupt ah=9h print $ terminated string
mov dx, offset msg ; Address of msg
int 21h ; Int 21h/ah=9h Print msg
mov outchar, 48+2 ; Move ASCII val for `2` to outchar buffer
mov dx, offset outchar ; Address of the $ terminated outchar buffer in DX
int 21h ; AH is still 9h, so this prints $ terminated string
mov ax, 4c00h ; Exit program with return value 0
int 21h
endp
msg db "Testing$" ; msg string
outchar db ?, "$" ; output buffer for single character terminated with $
end main
你可以直接使用ASCII值,而不是像这样写:mov outchar, 48+2
mov outchar, '2'
或者您可以通过一次调用INT 21h/AH=9h来完成,方法是将您想要的字符放入输出缓冲区的中间:
main proc
mov outchar, '2' ; Place the ASCII value for '2' in the output buffer
mov ah, 09h
mov dx, offset msg
int 21h ; Print $ terminated string starting at `msg`
mov ax, 4c00h
int 21h ; Exit with error code 0
endp
msg db "Testing"
outchar db ?, "$"
这个方法有效的原因是,
INT 21h/AH=9h会从偏移量
msg
开始盲目打印直到找到终止符
$
。我们首先对
outchar
处的字符进行替换,这样当执行
INT 21h/AH=9h时,它将在内存中遇到
Testing2$
。一旦遇到
$
,它就会停止打印,输出看起来像这样:
Testing2
您还可以选择使用两个不同的 DOS (INT 21h) 中断。虽然 INT 21h/AH=9h 打印一个以$
结尾的字符串,INT 21h/AH=2h 显示一个单个字符:
DOS 1+ - 写入标准输出字符
AH = 02h
DL = 要写入的字符
返回:
AL = 上次输出的字符(尽管官方文档没有说明会返回任何内容)(至少在 DOS 2.1-7.0 中)
您可以像之前一样编写程序以显示 msg
字符串,但是您也可以使用 INT 21h/AH=2h 来显示单个字符。您的代码可能看起来像这样:
.model tiny
.code
org 100h
main proc
mov ah, 09h ; DOS Interrupt ah=9h print $ terminated string
mov dx, offset msg ; Address of msg
int 21h ; Int 21h/ah=9h Print msg
mov ah, 02h ; DOS interrupt ah=2h print single character
mov dl, '2' ; DL = ASCII value of character to print
int 21h ; Int 21h/ah=2h print single character in DL
mov ax, 4c00h ; Exit program with return value 0
int 21h
endp
msg db "Testing$" ; msg string
end main
Testing$
字符串以$
终止。 - 500 - Internal Server Error