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$。
一旦到达$,它将停止打印,因此输出如下所示:
测试2
您还可以选择使用两个不同的 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