Как ввести шестнадцатеричный в двоичный файл, используя прерывание DOS в сборке?
Следующий код включает шестнадцатеричное число (относящееся к коду ASCII, предположим, что оно получено с клавиатуры), я хочу вывести это шестнадцатеричное число на экран, но в "двоичном", используя прерывание DOS. NUMLOCK - 45 часов.
[org 0x0100]
mov AL, 45 ;moving NUMLOCK hexademical(ASCII code) to AX
~~How to display its binary relevant to screen using DOS Interrupt?
1 ответ
DOS Interrupt имеет только эти сервисы, выводящие на экран:
AH = 02h - ЗАПИСАТЬ ХАРАКТЕР ДЛЯ СТАНДАРТНОГО ВЫХОДА
AH = 06h - ПРЯМОЙ ВЫХОД КОНСОЛИ
AH = 09h - НАПИШИТЕ СТРИНД В СТАНДАРТНЫЙ ВЫХОД
AH = 40h - "ЗАПИСЬ" - ЗАПИСЬ В ФАЙЛ ИЛИ УСТРОЙСТВО (при вызове с помощью дескриптора файла STDOUT или STDERR)
Все они только копируют значение из входных данных в выходные, без каких-либо преобразований или форматирования, поэтому обычно вводимые данные должны быть символом или строкой ASCII или двоичным байтовым массивом.
Но вы должны понимать, что компьютеры работают в двоичном режиме (слабый ток / большой ток, который часто интерпретируется как 0 или 1). Это не понимает никакой другой ценности.
Поэтому, когда у вас есть ценность 69
в регистре процессора al
, al
создается из 8-битных ячеек на чипе ЦП, и эти ячейки устанавливаются как "0 1 0 0 0 1 0 1". Ячейки называются битами. Поэтому, когда вы пишете в сборке источника mov al,45h
ассемблер во время компиляции создает эту двоичную форму для вас и сохраняет ее в машинный код как один байт, потому что это как mov al,imm8
Инструкция ожидает закодированное значение.
Таким образом, все, что вам нужно сделать для "двоичной строки", это идти по битам слева направо, 8 раз и выводить символ '0'
или же '1'
на экран, в зависимости от того, установлен ли конкретный бит или установлен.
Если ваша задача состоит в том, чтобы отобразить число в любой другой базе (например, основание 10 = десятичное число), вам нужно будет выполнить сложный расчет, чтобы узнать конкретные цифры '6'
а также '9'
формируя десятичный формат "69".
Любая основа степени двоичности немного проще, потому что вам нужно просто извлечь группу битов (например, в шестнадцатеричной базе 16 каждая цифра составляет ровно 4-битную часть значения, обратите внимание, как 45h
в двоичном 0100
(4) и 0101
(5). Но вам все равно придется вычислять группы битов.
Только двоичный вывод базы 2 в основном готов к печати, потому что это родной способ, которым компьютер хранит числовые целочисленные значения в регистрах и памяти.
Очень важно, чтобы вы поняли, что такое биты, и что это значит, что al
8-битный регистр, и ax
16-битный регистр, и ah
верхние 8 бит ax
и т. д. Если вы не понимаете, как работает двоичная математика и как эти значения кодируются в битах, у вас будут трудные времена с очень простыми задачами сборки, такими как эта.
Вот почему я даже не добавляю здесь никакого кода, потому что вам нужно сначала проработать свою математику, чтобы полностью понять, что означает " значение N" кодирования значения.
После того, как вы поймете, с чем работает компьютер, вы, скорее всего, сможете быстро проверить некоторые побитовые инструкции, такие как сдвиги или тесты, и выполнить проверку битов + вывод 0/1 в экранную петлю. Это очень простая задача, когда ты это понимаешь.
РЕДАКТИРОВАТЬ: Я решил дать вам что-то более наглядное, я написал "Показать двоичное 8-битное значение" в "Простой 8-битный Ассемблер".
Это не 8086, но:
- инструкции "одинаковые" (просто очень ограниченный набор, а не полный 8086)
- регистры совершенно разные (четыре 8-битных общего назначения A, B, C, D и два специализированных указателя PC и SP)
- структура памяти совершенно иная (всего 256 байтов от общего объема памяти, последние 24 байта предназначены для отображения "вывода")
- Принципы те же, если вы поймете это, 8086 будет выглядеть намного проще, просто намного мощнее и проще в коде (больше инструкций).
Поместите следующий код на страницу: http://schweigi.github.io/assembler-simulator/
И используйте "Шаг", чтобы медленно перейти от инструкции к инструкции и посмотреть на "память" и "зарегистрировать" представления справа, чтобы увидеть, что делает инструкция (вы можете использовать справочное руководство по инструкции x86, чтобы прочитать, что должна делать инструкция, я думаю, все описания подойдут и к этому простому ассемблеру (хотя некоторые из них не на 100% правильны относительно флагов, но вы не заметите и лучше изучите 8086 инструкций с самого начала)).
; init input values
MOV A, 0x45 ; A = 45h (this ASM needs "0x" for hexa)
MOV D, 240 ; point to output display after last digit
MOV C, 8 ; 8 chars (representing bits) to output
print_loop:
; convert lowest bit of A into ASCII digit '0' or '1'
MOV B, A ; copy of A (to preserve A value)
AND B, 1 ; extract lowest bit of A (B = 0 or 1)
ADD B, '0' ; turn the value 0/1 into ASCII '0'/'1'
; display '0' or '1' to "Output" window
MOV [D], B ; write the digit to output
DEC D ; update output pointer
; shift all bits in A to right by 1 position
SHR A, 1
; create space after 4 bits displayed
CMP C, 5 ; 8-3 = 5, fourth DEC is below (in future)
JNE .no_space
DEC D ; skip one position in output
.no_space:
; loop until 8 bits are displayed
DEC C ; counter of bits
JNZ print_loop ; repeat until C becomes 0
; stop simulator
HLT
Тогда вы можете подумать, как вы можете превратить это в версию 8086.
Я бы посоветовал повернуть логику цикла, чтобы перейти от самого верхнего бита, это проще с 8086, так как вы можете использовать гораздо больше инструкций, например, adc
(например, вы можете попытаться выяснить, что является результатом mov dl,24
adc dl,dl
... это может быть довольно интересно после shl
). Затем вы можете вывести цифры напрямую int 21h,2
(если вы измените логику для проверки битов слева направо).
Или вы можете сохранить ту же логику и сохранить цифры ASCII в буфере памяти с конца (убедитесь, что у вас достаточно большой буфер), и распечатать его одним int 21h, 9
,
Или... существует миллион других способов вычисления того же результата (вывод на экран "0100 0101" цифр ASCII от исходного значения 45h
). Это только вывод правильного числа в правильном месте и времени, то, как вы рассчитываете, не имеет значения, пока ваш результат верен.