3

我的汇编语言代码有问题。

我们被要求提示用户输入字符串,我们应该再次显示它或将其回显到命令行。我们需要假设它最多只有 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
4

1 回答 1

2

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

012345678901234567890

奇怪的是,当要求输入最多 20 个字符时,您可能会收到 21 个字符!


 1 mov ah, 0Ah                         
 2 lea dx, myBStr                      ;Load address of string
 3 int 21h
 4 mov ah, 9h                          ; show message of entered string
 5 int 21h
 6 lea dx, message2                    ;load second message to dx
 7 mov ah, 9h                          ;show this message
 8 int 21h
 9 mov ah, 0Ah                         
10 lea dx, myBStr                      ;Load address of string
11 int 21h 

第 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 个字节开始。这就是为什么你需要写lea dx, myBStr + 2.


message2 db "The string you entered is: " , 13, 10, 'S'

最后的“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 个强制回车 CR 的空间。
第二个字节(0)将由 DOS 设置为实际输入的字符数(不包括 CR)。在输出字符串之前,您可以使用此字节正确地“$”终止字符串。

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

正如prl 所指出的,如果您要设置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 实际指定退出代码。in 的零AL表示正常的程序终止。

于 2017-10-29T16:49:32.320 回答