m68k От шестнадцатеричного до десятичного не работает правильно - PullRequest
0 голосов
/ 21 декабря 2011

Я пишу небольшую ОС для компьютера M68k, которую я разрабатываю, и у меня возникла небольшая проблема. Мне нужно иметь возможность показывать пользователю шестнадцатеричное значение (скажем, $ 1F) в десятичном виде (31). Я написал следующий код для этого, но у него есть несколько проблем:

ConvertHexByteToDecimal:
    move    sr, -(sp)        ; Back up status register to stack.
    move    #$2700, sr       ; Disable interrupts.

    move.b  d2, -(sp)        ; Back up d2 to the stack.

    and.b   #$0F, d2         ; Get rid of the high nybble
    cmp.b   #$9, d2          ; Is the low nybble in the range of 0-9?
    bgt.s   @convertHex      ; If not, branch.

    move.b  (sp)+, d3        ; Restore the 10's place from the stack
    and.b   #$F0, d3         ; Get rid of the low nybble
    add.b   d3, d2           ; Add the 10's place.

    bra.s   @done            ; If so, branch.

@convertHex:
    sub.b   #$A, d2          ; Subtract $A from the hexadecimal meeper.

    move.b  (sp)+, d3        ; Restore the 10's place from the stack
    and.b   #$F0, d3         ; Get rid of the low nybble
    add.b   #$10, d3         ; Add 1 to the 10's place.
    add.b   d3, d2           ; Add the 10's place to the number.

@done:
    move.b  d2, d1           ; Copy to output register.
    move    (sp)+, sr        ; Restore status register.
    rts                      ; Return to sub.

Код прекрасно работает со значениями до $ F. Например, если я введу $ B, он выдаст 11. Однако, как только цифры идут за $ F, он начинает ломаться. Если я введу 10 долларов, я получу 10, и так далее. Он всегда возвращается после $ xF.

У кого-нибудь есть идеи, почему он это делает?

1 Ответ

3 голосов
/ 21 декабря 2011

Если вы пытаетесь вывести число в виде десятичной дроби, вы не сможете сделать это, обрабатывая один кусочек за раз.Полномочия двух и десяти степеней не связаны, кроме 10<sup>0</sup> == 2<sup>0</sup> == 1.

Все остальные неотрицательные степени 10 заканчиваются на 0, а неотрицательные степени двух заканчиваются 2,4, 6 или 8 (никогда 0).

Чтобы решить эту проблему, идея состоит в том, чтобы использовать деление на десять, чтобы получить то, что вы хотите.Подобный сборке псевдо-код, такой как:

    // Desired value is in num

    push num                       // example $1f/31
    if num < 100 goto tens         // no hundreds, so skip
    val = num / 100 + '0'
    output val
    num = num % 100

tens:
    if num < 10 goto ones          // is >= 10 so do this bit
    val = num / 10 + '0'           // gives us '3'
    output val
    num = num % 10                 // remainder is 1

ones:
    val = num + '0'                // gives us '1'
    output val
    pop num

Обратите внимание, что мы выполняем те же операции, что и ваш код, но вы фактически выполняете деление и модуль по модулю base-16, а не base-10.

Вам придется самостоятельно конвертировать этот псевдокод в 68k, прошло уже около двух десятилетий с тех пор, как я сократил код для этого чипа.

...