Assembly 如何在汇编语言编程中提示用户输入字符串并再次显示
我的汇编语言代码有问题 我们被要求提示用户输入字符串,我们应该再次显示它或将其回显到命令行。我们需要假设它最多只有20个字符(在字符串中) 这是示例输出: 输入一个字符串(最多20个字符)。 012345678901234567890 您输入的字符串是: 012345678901234567890 在DOSBOX中运行代码时,输入:0123456789 点击回车键后,我看到一堆看起来很奇怪的字符和符号 这是我的密码:Assembly 如何在汇编语言编程中提示用户输入字符串并再次显示,assembly,masm,x86-16,dosbox,dox,Assembly,Masm,X86 16,Dosbox,Dox,我的汇编语言代码有问题 我们被要求提示用户输入字符串,我们应该再次显示它或将其回显到命令行。我们需要假设它最多只有20个字符(在字符串中) 这是示例输出: 输入一个字符串(最多20个字符)。 012345678901234567890 您输入的字符串是: 012345678901234567890 在DOSBOX中运行代码时,输入:0123456789 点击回车键后,我看到一堆看起来很奇怪的字符和符号 这是我的密码: .186 data segment
.186
data segment
message1 db "Enter a string (max 20 char.): " ,13, 10, '$'
message2 db "The string you entered is: " , 13, 10, 'S'
myBStr db 20, 21 dup(?) ,'S'
data ends
stack1 segment stack
db 100 dup(?) ; This is the stack of 100 bytes
stack1 ends
code segment
assume cs:code, ds:data, ss:stack1
start:
mov ax, data
mov ds, ax
mov ax, stack1
mov ss, ax
lea dx, message1 ;load message to dx
mov ah, 9h ;show this message
int 21h
mov ah, 0Ah
lea dx, myBStr ;Load address of string
int 21h
mov ah, 9h ; show message of entered string
int 21h
lea dx, message2 ;load second message to dx
mov ah, 9h ;show this message
int 21h
mov ah, 0Ah
lea dx, myBStr ;Load address of string
int 21h
mov ah, 4ch ;Set up code to specify return to dos
int 21h
code ends
end start
输入字符串(最多20个字符。)
012345678901234567890
奇怪的是,当要求输入最多20个字符时,您可能会收到21个字符
第4行和第5行不合适。在显示第二条消息后,您需要此代码。
第9行、第10行和第11行当前重新输入字符串,而实际上您希望显示它
lea dx, myBStr ;Load address of INPUT STRUCTURE
mov ah, 0Ah ;Buffered input
int 21h
lea dx, message2 ;Load second message
mov ah, 09h ;Show this message
int 21h
lea dx, myBStr + 2 ;Load address of string
mov ah, 09h ;Show entered string
int 21h
字符串从输入结构的第3个字节开始。这就是为什么您需要编写leadx,myBStr+2
最后的“S”没有真正的意义。让我们承认这是一个打字错误,然后写:
message2 db "The string you entered is: " , 13, 10, '$'
由于您希望能够获得20个字符的字符串,因此需要为DOS.BufferedInput函数0Ah设置不同的输入结构:
myBStr db 21, 0, 21 dup(0)
第一个字节(21)告诉DOS存储空间(21 dup(0)
)有空间容纳20个字符和1个强制回车符。DOS将使用实际输入的字符数(不包括CR)设置第二个字节(0)。您可以使用此字节正确地“$”—在输出字符串之前终止该字符串
mov bl, [myBStr + 1] ;Get length of string
mov bh, 0
mov byte ptr [myBStr + 2 + bx], '$' ;Replace CR with '$'
lea dx, myBStr + 2 ;Load address of string
mov ah, 09h ;Show entered string
int 21h
如前所述,如果要设置
SS
段寄存器,则还要设置SP
寄存器:
mov ax, stack1
mov ss, ax
mov sp, 100
然而,通常你根本不需要写这些行
根据评论 只是一个小问题,我怎样才能把字符串打印出来 在退出DOS之前,只需等待用户按任意键即可
mov ah, 07h ;DOS.InputCharacterWithoutEcho
int 21h
mov ax, 4C00h ;DOS.TerminateWithExitcode
int 21h
请注意,最好实际使用DOS函数4Ch指定exitcode。
AL
中的零表示正常的程序终止。在两个位置,您有'S'
,在这两个位置,您应该有'$'
,当您试图在最后打印myBstr时,您使用了错误的中断号。您使用0ah
,输出值应为09h
。此外,字符串实际上从myBstr+2
开始,而不是myBstr
,因为前2个字节用于输入中断调用。输出时应跳过这两个字节。在底部将lea dx,myBStr
更改为lea dx,[myBStr+2]
您可能希望将myBStr db 20,21 dup(?),'S'
更改为myBStr db 20,22 dup('$)
与您的问题无关,但您应该在加载ss时加载sp。在编写的代码中,sp仍然包含到上一堆栈段的偏移量,该偏移量不再有效。@MichaelPetch非常感谢您!这很快,真的很有帮助!不过,这只是一个小问题,在我按下enter键后,如何保持字符串打印出来?现在,(在更改您所说的内容后)它只打印以下内容:输入一个字符串(最多20个字符)。您输入的字符串是:012345678901234567890
mov ax, stack1
mov ss, ax
mov sp, 100
mov ah, 07h ;DOS.InputCharacterWithoutEcho
int 21h
mov ax, 4C00h ;DOS.TerminateWithExitcode
int 21h