Преобразование шестнадцатеричных цифр в соответствующие десятичные цифры - PullRequest
0 голосов
/ 24 марта 2020

поэтому у меня есть этот вопрос на домашнем задании, и я не знаю, правильно ли я его понимаю. он говорит: * Написать ассемблерный код для преобразования упакованного байта BCD из AL в двоичный файл. Пример: предположим, что Al = 35H, который представляет десятичное число 35. Его следует преобразовать в 00100011 = 23H = 2 * 16 + 3 = 35d. * Из того, что я понимаю, мне нужно преобразовать цифры шестнадцатеричного числа в цифры десятичное число. это от 35 до 35 дней. кто-то может подтвердить, если это то, что он спрашивает? и если да, может ли кто-нибудь помочь мне с алгоритмом, чтобы сделать это?

1 Ответ

0 голосов
/ 25 марта 2020

Как прокомментировал @Michael, вам просто нужно вычислить (al >> 4) * 10 + (al & 0Fh).

Очевидно, вы можете предположить, что вход является правильным BCD с обоими полубайтами байта между 0 и 9, сохраняя отдельные десятичные цифры.

Обратите внимание, что это не произвольная шестнадцатеричная строка, и она даже не сохраняется с цифрами в ASCII. Таким образом, вам не нужно ничего делать, чтобы справиться с тем фактом, что ASCII '0' .. '9' имеет пробел перед 'A' .. 'F', как если бы вы фактически рассматривали строку di git как не нормализованное основание 10 со значениями di git, равными 0..15, в местах значений, равными 10 ^ n.

Вы только что упаковали BCD. И да, интерпретация этих битов с помощью base-16 даст вам 0x35.

Но вам нужно двоичное целое число, которое представляет собой то же значение, что и обработка этих кусочков как десятичных цифр, со значением места 10 ^ n. Таким образом, вы разделяете полубайты и умножаете верхний на 10.


Если вас не интересует производительность, вы можете использовать устаревшие инструкции ASCII / BCD для x86. Они доступны в 16 и 32-битных режимах. (x86-64 удалил инструкции BCD). Единственным преимуществом здесь является размер кода: две 2-байтовые инструкции могут выполнять работу медленно.

    aam 16          ; split AL into AH = AL/16; AL = AL%16
    aad             ; AL = AH*10 + AL;  AH=0

aam использует деление, поэтому оно может работать в любой момент; использование его со степенью 2 очень неэффективно для производительности, только для размера кода. Предполагаемое использование - это разбиение двоичного целого числа на 2 неупакованных десятичных знака (ASCII Adjust AX After Multiply) с непосредственным делителем по умолчанию 10.

Непосредственным немедленным использованием AAD также является 10, который мы хочу.

https://www.felixcloutier.com/x86/aam и https://www.felixcloutier.com/x86/aad.

Нет инструкции dad, которая бы выполняла такое же умножение на упакованном BCD в AL только DAA и DAS (после сложения / вычитания).


Эффективное выполнение (для производительности, а не для размера кода) оставлено в качестве упражнения для читателя. (Или для компилятора; G CC делает хорошую работу, используя 2x LEA для умножаемой части: https://godbolt.org/z/K-tjXv)

...