упакованный десятичный код в ascii ассемблер

Я пытаюсь преобразовать упакованные десятичные числа в строки ascii. Вот мое понимание до сих пор:

Последующий:

bcd BYTE 34h

Должен преобразовываться в десятичное число 34 после «распаковки». Теперь я не уверен, как лучше всего это сделать. Если я преобразую это шестнадцатеричное число в двоичное, оно будет следующим...

0011 0100 

Теперь, если моя процедура распечатывает каждое 4-битное двоичное значение за раз, тогда она должна печатать строку чисел ascii, верно? Итак, если я пройду цикл, возьму первое 4-битное двоичное число, распечатаю его фактическое значение, оно напечатает 3.. затем сделает то же самое, оно напечатает 4.

Итак, вот моя общая идея:

Возьмите 8-битное значение «34h», переместите его в AH и AL. В AH очистите вторую половину битов, используя следующее:

and ah, 11110000b

и в AL очистите первую половину битов, используя следующее:

and al, 00001111b

Итак, AH = 0110b или 3 и AL = 0100b или 4, затем распечатайте их соответственно.

Хороший ли это подход? Или я говорю совершенно неправильно или слишком много думаю об этом?

РЕДАКТИРОВАТЬ: вот мое окончательное решение с исходным значением 12345678h. Спасибо всем, кто помог!

;-----------------------------------------------------------------------------
PackedToAsc PROC USES eax ebx edx ecx esi
; This function displays a packed decimal value in its "ascii" form
; i.e. 12345678h would display decimal, 12345678 in decimal form
; 
; Requires ECX = SIZEOF packed decimal
;          ESI to be pointing to the packed decimal
;-----------------------------------------------------------------------------
mov edx, [esi]              ; temp store our offset
mov eax, 0                  ; clear eax
mov ebx, 0                  ; clear ebx

L1: rol edx, 8              ; rotate left 8 bits to avoid little endian 
    mov [esi], edx          ; mov our temp back to the actual value

    mov al, BYTE PTR [esi]  ; al = 12h  0001 0010
    mov bl, BYTE PTR [esi]  ; bl = 12h  0001 0010
    shr al, 4               ; al = 0000 0001
    and bl, 00001111b;      ; bl = 0000 0010
    add al, 48              ; convert to ascii
    call WriteChar          ; display al
    mov al, bl
    add al, 48              ; convert to ascii
    call WriteChar          ; display bl
    loop L1

    call Crlf
ret
PackedToAsc END

P


person Dalton Conley    schedule 09.11.2010    source источник
comment
Подход выглядит нормально. Когда дело доходит до кода на уровне ассемблера, под рукой не так много вариантов.   -  person Shamim Hafiz    schedule 09.11.2010
comment
@Gunner: Нет, это не так. Он манипулирует цифрами, а не упаковывает и распаковывает двоично-десятичные числа.   -  person slashmais    schedule 09.11.2010


Ответы (1)


BCD использует только цифры от 0 до 9.
Неупакованная цифра BCD использует младший полубайт всего байта, и для преобразования ее в ASCII вы добавляете 48.
Число 34h представляет собой десятичное число 52 и будет представлено как неупакованный BCD как 00000101 и 00000010
(изменено во избежание путаницы при использовании встроенных инструкций) Когда он упакован: 01010010 == BCD упакованный 52

Чтобы распаковать его, вы можете сделать то же самое, но вам нужно сдвинуть AH вправо, чтобы поместить значение в младшую часть. Чтобы преобразовать в ASCII, просто добавьте 48.

[редактировать]

MASM (=> ВСЕ инструкции, включая Linux), работающий на процессорах 80x86, использует схему с прямым порядком байтов. ЦП, такие как Motorola 68000 (Apple Mac) и RISC, используют обратный порядок байтов.

Когда вы сохраняете число в формате BCD, младший байт находится в самом младшем адресе до самого старшего в самом высоком, например:

my_unpacked_bcd  DB 4,3,2,1 ; this is the decimal number 1234
my_packed_bcd    DW 3412h  ; this defines the same number as packed

Упакованный BCD зависит от того, что вы хотите с ним делать. Если вы хотите ADD, MUL, DIV, SUB, вы должны представить значения в соответствии с требованиями этих инструкций. Также не забудьте добавить нулевые байты в начало и конец ваших цифр для хранения переносов.

person slashmais    schedule 09.11.2010
comment
Хорошо, имеет смысл, но теперь я прихожу к небольшой проблеме с порядком байтов. Скажем, у меня есть упакованное десятичное число.. bcd BYTE 12345678h, если я сделаю что-то подобное... mov al, BYTE PTR bcd, я получаю число 78 для начала, какие-либо предложения, как избежать этого? - person Dalton Conley; 09.11.2010
comment
@Dalton Conley: я обновил свой ответ, чтобы дать вам больше указаний - person slashmais; 10.11.2010
comment
Для прямого порядка байтов упакованный BCD 12345678h будет иметь вид 78563412 при распаковке, если вы будете следовать обычным методам. Если вы просто хотите уменьшить объем памяти, занимаемый числом, хранящим его в виде упакованного BCD, ваш подход в порядке, но вы должны помнить о корректировке своих значений, когда хотите их использовать. - person slashmais; 10.11.2010