Как запросить у пользователя строку и снова отобразить ее на языке программирования ассемблера

У меня проблемы с кодом ассемблера.

Нас попросили ввести строку ввода для пользователя, и мы должны снова отобразить ее или передать в командную строку. Мы должны предположить, что это только до 20 символов (в строке)

Это пример вывода:

Введите строку (максимум 20 символов)

012345678901234567890

Введенная вами строка:

012345678901234567890

Когда я запускаю свой код в DOSBOX, я ввожу: 0123456789 После нажатия Enter, он показывает мне кучу символов и символов, которые выглядят странно...

Вот мой код:

.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

1 ответ

Введите строку (максимум 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 не на своем месте. Вам нужен этот код после отображения 2-го сообщения.
Строки 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) 

1-й байт (21) сообщает DOS, что место для хранения (21 dup(0)) есть место для 20 символов и 1 обязательный возврат каретки CR.
2-й байт (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

Как отмечалось, если вы собираетесь установить 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. Ноль в AL сигнализирует нормальное завершение программы.

Другие вопросы по тегам