我在Assembly 8086中构建了一个代码,它从用户那里得到一个字符串,然后将其打印出来。
这是我的代码:
call displayNewLine ;Displays a new line
mov [byte ptr si + 14], '$' ;Set's the last char in the string to a $
add si, 2 ;Prevent from showing the first two chars (When receiving a string)
mov dx, si ;SI contains the offset where the string starts
mov ah, 09h
int 21h
当我运行它时,它只显示几个空格(从它看起来它只打印出字符串和$之间的字符。)
截图:
但是,由于某种原因,当我添加另一个int 21h
时,它可以工作:
call displayNewLine ;Displays a new line
mov [byte ptr si + 14], '$' ;Set's the last char in the string to a $
add si, 2 ;Prevent from showing the first two chars (When receiving a string)
mov dx, si ;SI contains the offset where the string starts
mov ah, 09h
int 21h
int 21h
出于某种原因,此代码有效,而在第二个int 21h
上,它会显示实际文本。
截图:
displayNewLine:
proc displayNewLine ;A function that displays a new line
mov dl, 10
mov ah, 2
int 21h
ret
endp displayNewLine
我试图将carrige移回右侧,但同样发生了。
是什么原因导致第一次不显示文字?
如果您需要更多详情或更好的解释,请发表评论!
答案 0 :(得分:3)
这可以归结为这样一个事实,即您已经对'$'
的放置位置进行了硬编码。
如果我们用空格或NUL字节之外的其他东西初始化缓冲区会更容易看到发生了什么,例如:
buf: db 10,0,'0123456789ABCDEF'
现在,int 21h / ah=0ah
的说明指出,buf+2
您最终会以“[实际字符读取],包括最终回车 “
因此,如果您输入“test”,之后您的缓冲区将如下所示:
10,0,'test\r56789ABCDEF' ; \r == carriage return
然后你决定将'$'
终结符放在buf+14
,给你:
10,0,'test\r56789AB$DEF'
现在从buf+2
开始打印,这与您打印test\r56789AB','$'
时的打印方式相同。
“test”将打印,但随后滑块返回结果,光标移回当前行的开头,并从那里打印其余字符(“56789AB” )。
当您第二次执行中断时,当前行上已经有“56789AB”,然后打印“test”导致“56789ABtest”,回车再次将光标移动到当前行的开头行,其余字符被打印出来(因此“56789AB”将打印在已经存在的“56789AB”上。
如果你用空格或NUL字节初始化缓冲区而不是“01234 ...”,那么当你使用一个中断时,看起来好像没有打印过,当你使用两个中断时,你会得到一些东西像:
C:\>program
test
test
TL; DR:您的输入字符串将包含回车符,您应该将'$'
放在回车符的位置而不是硬编码的位置[si+14]
。