Преобразование шестнадцатеричного числа ASCII в 32-битное двоичное целое число в x86

Итак, я читаю 8-значный ввод пользователя и сохраняю его в переменную. Например:

Введите 8-значный шестнадцатеричный номер: 1ABC5678.

Итак, затем я перебираю шестнадцатеричное число 1ABC5678 и вычитаю 48 из чисел 0-9 и вычитаю 55 из AF, чтобы получить числовое представление ввода. но это кажется неправильным. Моя цель - преобразовать этот 8-значный шестнадцатеричный в восьмеричный. Я уже знаю, как перейти от двоичного к восьмеричному, маскируя и сдвигая 32-битную двоичную цифру. Но моя проблема в том, что мой подход к получению двоичного файла неверен.

Я кодирую на Intel IA-32. х86.

ОБНОВЛЕНИЕ

Теперь я получил 32-битный двоичный файл для двоичного имени переменной. Я хочу преобразовать его в восьмеричное. Любые идеи о том, как сдвинуть 3 на 3, чтобы получить правильное восьмеричное число?

Это мой код до сих пор:

; Now we have the Binary digits saved into the binary variable
; Lets convert into octal

octal_init:
mov     ecx, 11             ; initialize count
mov     edi, octal             ; point to start of new string
mov     eax, [binary]               ; get a character
MOV     edx, 00000000000000000000000000000000b ;Clear EDX

octal_cont:
MOV     dl, al
SHL     dl, 5
SHR     dl, 5

octal_top:
mov     [edi], dl               ; store char in new string
inc     edi                     ; update dest pointer
SHR     eax, 3
dec     ecx                     ; update char count
jnz     octal_cont                  ; loop to top if more chars

person Shar    schedule 15.10.2012    source источник
comment
Наверняка есть библиотеки для такого рода вещей?   -  person spender    schedule 15.10.2012
comment
Что ж, я знаю, что если вы возьмете каждую цифру из шестнадцатеричного числа, преобразуете его в двоичное число и поместите двоичное число рядом друг с другом, то вы получите 32-битное двоичное число этого шестнадцатеричного числа. но есть проблема с тем, что Intel является маленьким индейцем, а также с моим подходом к преобразованию его в двоичный код.   -  person Shar    schedule 15.10.2012
comment
Ваше решение работает только для верхнего регистра, вы не вводите нижний регистр, не так ли? И вы не упоминаете о смещении результата влево.   -  person Mark Ransom    schedule 15.10.2012
comment
Да, поэтому, если пользователь вводит какой-либо последний из A-F, который не является заглавным, я сначала преобразую их в верхний регистр, используя этот код: code и др., 11011111b code   -  person Shar    schedule 15.10.2012
comment
Когда вы конвертируете каждую цифру, сдвиньте предыдущий результат влево на 4 бита и or введите в него новое значение. Это должно сработать.   -  person Mark Ransom    schedule 16.10.2012
comment
@MarkRansom Большое спасибо!! очень полезный совет!   -  person Shar    schedule 16.10.2012
comment
@AntoineMathys Я только что добавил свой код, дайте мне знать, если вы знаете исправление!   -  person Shar    schedule 16.10.2012


Ответы (2)


Вот некоторые из проблем:

  • входная строка заканчивается новой строкой, а не нулем
  • некоторые логические ошибки

Вы можете написать это так:

L1_init:
mov     ecx, 8                  ; initialize count
mov     esi, buf                ; point to start of buffer
mov     edi, binary             ; point to start of new string


L1_top:
mov     al, [esi]               ; get a character
inc     esi                     ; update source pointer

cmp       al, '0'               ; Compare al with ascii '0'
...
or        dl, al                           ; Merge in the four bits just computed
loop      L1_top                          ; Loop back for next byte to convert

mov     [edi], edx               ; store char in new string

L1_end:

Обратите внимание, что вы уже проверили, что у вас есть 8 символов, поэтому нет необходимости делать это снова в цикле.

person Community    schedule 16.10.2012
comment
Большое спасибо, Антуан. У меня сейчас работает бинарная часть. мне нужно преобразовать его в восьмеричное, что намного проще. я сдвигаю двоичное число 3 на 3 цифры и сохраняю символ. - person Shar; 16.10.2012
comment
Я обновил свой код, поэтому теперь у меня есть 32-битная двоичная цифра, и я хочу преобразовать ее в восьмеричную путем сдвига. Не могли бы вы посмотреть на мой код? - person Shar; 16.10.2012

Самый простой способ преобразовать строку Hex в значение int — использовать либо strtol(), либо strtoll(), либо strtoimax():

#include <inttypes.h>
#include <stdlib.h>

intmax_t     max;
long         l;
long long    ll;
const char * str = "1ABC5678";

max = strtoimax(str, NULL, 16);
l   = strtol(str, NULL, 16);
ll  = strtoll(str, NULL, 16);

В качестве альтернативы вы можете написать код вручную, если хотите:

int          pos;
long         l;
const char * str = "1ABC5678";

l = 0;
for(pos = 0; str[pos]; pos++)
{
    l = l << 4; // each Hex digit represents 4 bits

    // convert ASCII characters to int value
    if ((str[pos] >= '0') && (str[pos] <= '9'))
       l += (str[pos] - '0') & 0x0F;
    else if ((str[pos] >= 'A') && (str[pos] <= 'F'))
       l += (str[pos] - 'A' + 10) & 0x0F;
    else if ((str[pos] >= 'a') && (str[pos] <= 'f'))
       l += (str[pos] - 'a' + 10) 0x0F;
};
person David M. Syzdek    schedule 15.10.2012
comment
Большое спасибо за помощь, я пишу это на ассемблере, вы случайно не знаете, как это будет примерно выглядеть в .asm? - person Shar; 15.10.2012