Assembly 如何在汇编语言编程中提示用户输入字符串并再次显示

Assembly 如何在汇编语言编程中提示用户输入字符串并再次显示,assembly,masm,x86-16,dosbox,dox,Assembly,Masm,X86 16,Dosbox,Dox,我的汇编语言代码有问题 我们被要求提示用户输入字符串,我们应该再次显示它或将其回显到命令行。我们需要假设它最多只有20个字符(在字符串中) 这是示例输出: 输入一个字符串(最多20个字符)。 012345678901234567890 您输入的字符串是: 012345678901234567890 在DOSBOX中运行代码时,输入:0123456789 点击回车键后,我看到一堆看起来很奇怪的字符和符号 这是我的密码: .186 data segment

我的汇编语言代码有问题

我们被要求提示用户输入字符串,我们应该再次显示它或将其回显到命令行。我们需要假设它最多只有20个字符(在字符串中)

这是示例输出:

输入一个字符串(最多20个字符)。

012345678901234567890

您输入的字符串是:

012345678901234567890

在DOSBOX中运行代码时,输入:0123456789 点击回车键后,我看到一堆看起来很奇怪的字符和符号

这是我的密码:

.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