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