I'm writing a bunch of macros to deal with big numbers in MASM, and I have found myself needing to convert from a series of digits to a number. Basically, to get around MASM size restrictions, I've been passing bignums as strings. So, a bignum call would look something like:
MOV_BIG_NUM [eax], <1234567891011121314151617181920212223>
I've got an implementation that can handle (as far as I can tell) strings passed in bases that are powers of 2. That is, calls like:
MOV_BIG_NUM [eax], <1001101111010101101011110101000011101b> ;Base 2
MOV_BIG_NUM [eax], <0123456710121314151617202122232425262o> ;Base 8
MOV_BIG_NUM [eax], <123456789ABCDEF101112131415161718191Ah> ;Base 16
Will be handled fine. However, the method I'm using for those doesn't translate well (or indeed at all) to bases that are not powers of 2. The most important of these, of course, is decimal, but I'd love to get a method that functions with an arbitrary base. The method I've been using for powers of 2 has been to access bytes sequentially, shift the digits if necessary, and bitwise or
them with the existing digits. So my method for hexadecimal numbers looks something like this (This is a highly simplified version):
;foreach digit in list of digits
;eax contains the start of memory for the bignum
IF bit_offset EQ 0 ;Only move a new value in when the offset has just changed
mov ebx, dword ptr [eax + byte_offset] ;Get the current value at the dword's offset
ENDIF
digit = digit SHL bit_offset ;Shift the digit by a certain offset, so that we can store multiple digits in one byte
or ebx, digit
bit_offset = bit_offset + 4
IF bit_offset EQ ( 32 ) ;Number of bits in a dword
mov dword ptr [eax + byte_offset], ebx ;Move the dword back
byte_offset = byte_offset + 4 ;Number of bytes in a dword
bit_offset = 0;
ENDIF
;end foreach
However, this kind of approach obviously won't work for an arbitrary base. How would I go about converting a sequential list of decimal digits into a hex number?