упакованный десятичный в асси - PullRequest
4 голосов
/ 09 ноября 2010

Я пытаюсь преобразовать упакованные десятичные числа в строки 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

1 Ответ

2 голосов
/ 09 ноября 2010

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, младший байт находится от самого младшего адреса до самого старшего из самых высоких, например ::10000

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, вы должны представить значения в соответствии с этими инструкциями. Также не забудьте добавить нулевые байты в начале и конце ваших цифр для хранения переносов.

...