MS-DOS Debugger, перейти к следующей ячейке памяти

Я использую DosBox, и у меня есть строка, считанная из буфера с использованием прерывания. Я знаю, где первый символ хранится в памяти, как мне перейти к следующему символу?

0100 mov ah, 0a
0102 mov dx, 111
0105 int 21
0107 mov dl, [113]      ;first character here
010b mov ah, 02
010d int 21
010f int 20
0111 db 0f

Вопрос в том, как мне перейти к следующему символу в строке? Если я введу строку "Привет", а затем использовать inc dl это просто дает мне букву "я" вместо "е".

1 ответ

Решение

Вам нужно выбрать регистр, чтобы указать на текущий символ. Как только вы это сделаете, есть инструкции для продвижения вашего указателя, а также инструкции для чтения байта, на который указывает указатель.

Поскольку вы не знаете, сколько символов будет прочитано пользовательской функцией ввода, и вы хотите, чтобы эта функция работала с любым вводимым значением, вам понадобится какой-то цикл, чтобы вы печатали только столько символов, сколько было прочитано, хотя, если вы хотите сделать это проще, вы можете сделать так, чтобы он печатал только первые 3 символа независимо от того, что было напечатано. Я собираюсь предположить, что вы хотите распечатать именно то, что было введено пользователем.

Хороший способ справиться с этим - использовать инструкцию LOOP, которая повторяет (переходит в) тело цикла на счетчик, который был помещен в регистр CX. Поскольку функция пользовательского ввода дает нам количество символов, все, что нам нужно сделать, это прочитать это в нижнюю часть регистра CX (CL) для инициализации цикла. Нам также понадобится указатель для указания на текущий символ. Оказавшись в теле цикла, мы просто прочитаем любой символ по указателю "текущий символ" и затем вызовем функцию печати символов DOS, чтобы вывести его на консоль. Затем мы можем перемещать указатель и LOOP, пока все символы не будут выполнены. Обратите внимание, что каждый раз, когда встречается инструкция LOOP, CX уменьшается до тех пор, пока не достигнет нуля. Как только он становится равным нулю, LOOP больше не прыгает обратно в тело и просто переходит к инструкции, следующей за LOOP.

ПРИМЕЧАНИЕ. Если вы не выводите CRLF после чтения пользовательского ввода, перевод строки не будет выполняться, и новый вывод будет перезаписан в том месте, где ввод был прочитан на консоли. Фактически это будет выглядеть так, будто ничего не произошло.

Вот ваш модифицированный образец:

0100  MOV     AH,0A
0102  MOV     DX,0123
0105  INT     21            ;input string using buffer at 0123
0107  MOV     DX,0120
010A  MOV     AH,09
010C  INT     21            ;output CRLF sequence first
010E  MOV     SI,0124       ;point SI at byte containing chars read
0111  XOR     CX,CX         ;CX = 0
0113  MOV     CL,[SI]       ;CX = chars_read 
0115  INC     SI            ;mov SI to next char to display
0116  MOV     DL,[SI]       ;DL = character SI is pointing at
0118  MOV     AH,02
011A  INT     21            ;display character
011C  LOOP    0115          ;loop back to INC instruction until no more chars left
011E  INT     20            ;exit
0120  DB      0D            ;CR
0121  DB      0A            ;LF
0122  DB      24            ;"$" DOS string terminator
0123  DB      20            ;buffer start; max characters = 32
0124  DB      00            ;   chars read goes here
0125  DB      00            ;   input chars are read here
Другие вопросы по тегам