从汇编代码打印字符串时出错
Error while printing a string from assembly code
我是汇编新手,我学习的课程使用 EMU8086。我写这段代码来打印 Testing
和 50 的 ASCII 码,即数字 2
但它只打印 Testing
并忽略其余部分。怎么了?
.model tiny
.code
org 100h
main proc
mov ah, 09h
mov dx, offset msg
int 21h
mov ah, 4ch
mov dx ,0
mov dl, 2
add dl, 48
int 21h
endp
msg db "Testing$"
end main
阅读@500 - 内部服务器错误的评论后,我将代码更新为:
.model tiny
.code
org 100h
main proc
mov ah, 09h
mov dx, offset msg
int 21h
mov dl, 2
add dl, 48
int 21h
endp
msg db "Testing$"
end main
还是不行,怎么了?
DOS 中断 INT 21h/AH=9h 不打印字符值,它使用内存偏移到 $
终止字符串的开头打印。
DOS 1+ - WRITE STRING TO STANDARD OUTPUT
AH = 09h
DS:DX -> '$'-terminated string
Return:
AL = 24h (the '$' terminating the string, despite official docs which state that nothing is returned) (at least DOS 2.1-7.0 and NWDOS)
如果您想使用 INT 21h/AH=9h 打印出单个字符,那么您需要将该值移动到以 [= 结尾的缓冲区中14=] 符号。然后将该缓冲区的地址传递给 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+ - WRITE CHARACTER TO STANDARD OUTPUT
AH = 02h
DL = character to write
Return:
AL = last character output (despite the official docs which state
nothing is returned) (at least 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
你的第二个代码几乎没问题,你只是忘记了 ah
中的服务号码来告诉 int 21h
该怎么做:
.model tiny
.code
org 100h
main proc
mov ah, 09h
mov dx, offset msg
int 21h
mov ah, 2 ;<==== AH=2 : INT 21H WILL DISPLAY CHARACTER IN DL.
mov dl, 2
add dl, 48
int 21h
endp
msg db "Testing$"
end main
我是汇编新手,我学习的课程使用 EMU8086。我写这段代码来打印 Testing
和 50 的 ASCII 码,即数字 2
但它只打印 Testing
并忽略其余部分。怎么了?
.model tiny
.code
org 100h
main proc
mov ah, 09h
mov dx, offset msg
int 21h
mov ah, 4ch
mov dx ,0
mov dl, 2
add dl, 48
int 21h
endp
msg db "Testing$"
end main
阅读@500 - 内部服务器错误的评论后,我将代码更新为:
.model tiny
.code
org 100h
main proc
mov ah, 09h
mov dx, offset msg
int 21h
mov dl, 2
add dl, 48
int 21h
endp
msg db "Testing$"
end main
还是不行,怎么了?
DOS 中断 INT 21h/AH=9h 不打印字符值,它使用内存偏移到 $
终止字符串的开头打印。
DOS 1+ - WRITE STRING TO STANDARD OUTPUT
AH = 09h
DS:DX -> '$'-terminated string
Return:
AL = 24h (the '$' terminating the string, despite official docs which state that nothing is returned) (at least DOS 2.1-7.0 and NWDOS)
如果您想使用 INT 21h/AH=9h 打印出单个字符,那么您需要将该值移动到以 [= 结尾的缓冲区中14=] 符号。然后将该缓冲区的地址传递给 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+ - WRITE CHARACTER TO STANDARD OUTPUT
AH = 02h
DL = character to write
Return: AL = last character output (despite the official docs which state nothing is returned) (at least 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
你的第二个代码几乎没问题,你只是忘记了 ah
中的服务号码来告诉 int 21h
该怎么做:
.model tiny
.code
org 100h
main proc
mov ah, 09h
mov dx, offset msg
int 21h
mov ah, 2 ;<==== AH=2 : INT 21H WILL DISPLAY CHARACTER IN DL.
mov dl, 2
add dl, 48
int 21h
endp
msg db "Testing$"
end main