1

For example, I have: n1 db "1234" which represents a hexadecimal value. I would like to convert it to binary and store it inside 32-bit register, in this case the result would be: EAX = 0000 0000 0000 0000 0001 0010 0011 0100

What is the approach?

3
  • Curiously we do not have a canonical duplicate for hexadecimal number parsing yet. Commented Nov 13, 2022 at 11:56
  • 2
    Shift your result by 4 to the left and add the new digit which was converted from ascii depending on whether it was a letter or a digit. PS: 1234 is a misleading example/test case for hex. Commented Nov 13, 2022 at 11:59
  • total = total * base + digit (but note that digit isn't just char - '0' since letters and numbers aren't contiguous in ASCII.) For the other direction, binary integer to hex string, see How to convert a binary integer number to a hex string? for NASM, including scalar and SSE2/AVX2/AVX-512VBMI. For doing this efficiently, see Is there an algorithm to convert massive hex string to bytes stream QUICKLY? asm/C/C++ for an AVX2 version, and github.com/zbjornson/fast-hex Commented Nov 13, 2022 at 13:23

1 Answer 1

2

Inputting multi-radix multi-digit signed numbers with DOS shows how to do this particular conversion in the answer's code snippets 2a and 2b. You can also learn how to convert from octal and binary.
Don't be misguided by the mention "DOS". Many principles remain the same, and if you're currently clueless it will be a good starting point. You can change the code in accordance with your needs and skill level. And if that doesn't work out, then you can post a question including the code that you've tried.

Here's an adaptation of the mentioned snippets:

snippet 2a

    ; Hexadecimal
.a: inc   esi             ; Next character
    shl   eax, 4          ; Result = Result * 16
    movzx edx, byte [esi] ; -> DL = {["0","9"],["A","F"]} (NewDigit)
    cmp   dl, "9"
    jbe   .b
    sub   edx, 7
.b: sub   edx, 48
    or    eax, edx        ; Result = Result + NewDigit
    dec   ecx
    jnz   .a

snippet 2b with character validation and overflow detection

    ; Hexadecimal
.a: inc   esi             ; Next character
    movzx edx, byte [esi] ; -> DL = {["0","9"],["A","F"]} (NewDigit) ?
    cmp   dl, "9"
    jbe   .b
    sub   edx, 7
.b: sub   edx, 48
    cmp   dl, 15
    ja    .z              ; Stop if not a digit
    rol   eax, 4          ; Result = Result * 16
    test  al, 15
    jnz   .o              ; Overflow
    or    eax, edx        ; Result = Result + NewDigit
    dec   ecx
    jnz   .a
Sign up to request clarification or add additional context in comments.

2 Comments

If you weren't going to port your code to 32-bit, why bother repost it instead of just linking a 16-bit answer in a comment? Stuff like 4x rol ax,1 has no place in 32-bit code, only in code that might need to run on 8086. Also, what's up with branching in your binary version? cmp / adc ax,ax will shift in the new digit (and set CF if there's carry-out)
@PeterCordes I copied the snippets verbatim just for convenience. I didn't even notice that I had written them explicitly for 8086 two years ago.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.