|
-
December 30th, 2010, 03:47 PM
#5
Re: Decimal to hex conversion - problems in code
 Originally Posted by kamina
Now, what changes do I have to make in the program to convert even greater numbers that 65536?
Simplest part first: the output. Outputting a 32-bit hex number is about as simple as outputting a 16-bit number. Simply output the high-order 16 bit first, then the low-order 16 bits. If you don't leave any space between them you have a 32-bit hex number. Et voil*! 
Converting the input to a 32-bit binary number is a bit trickier: The MUL instruction you use already gives you a 32-bit result in DX:AX but that's not enough yet because it takes two 16-bit numbers as input while you need one that multiplies a 32-bit number by a 16-bit number giving a 32-bit result. Unfortunately, there is no such instruction in 16-bit x86 assembly. Therefore you need to multiply the high-order and low-order 16 bits of the 32-bit input value separately and add the partial results together. As I think it is about the same effort as explaining it, I modeled such a multiplication for you that you can use as a template. I did that in C++ inline assembler, though, to avoid the effort of using the actual assembler.
Code:
#define HIWORD(n) ((unsigned __int16)((n) >> 16))
#define LOWORD(n) ((unsigned __int16)((n) & 0xFFFF))
unsigned __int32 mul_32bit_by_16bit(unsigned __int32 a, unsigned __int16 b)
{
unsigned __int16 a_hi = HIWORD(a), a_lo = LOWORD(a);
unsigned __int32 result;
__asm {
xor dx,dx
mov ax,a_hi
mul b // Multiply high-order word
mov bx,ax // Put aside partial result in BX
xor dx,dx // Should be 0 anyway unless we hit an overflow, but to be sure...
mov ax,a_lo
mul b // Multiply low-order word
add dx,bx // Join the two partial results
// 32-bit result now is in DX:AX
shl edx,16 // Join result into 32-bit register for C++ function return
and eax,0FFFFh
or eax,edx
mov result,eax
}
return result;
}
Of course all that would be much simpler if you could use the 32-bit registers which are seamlessly available in 16-bit code as well as long as only the CPU supports them, but the .286 directive in your code seems to imply that this is not an option.
Keeping track of a 32-bit total instead of a 16-bit one occupies more registers of course, so you may need to either use the index registers SI and DI in addition to the GP registers or hold some temporary values in RAM storage.
And of course you need to increase the maximum number of decimal input digits that can be processed to 10 if you want to cover the entire 32-bit range.
I was thrown out of college for cheating on the metaphysics exam; I looked into the soul of the boy sitting next to me.
This is a snakeskin jacket! And for me it's a symbol of my individuality, and my belief... in personal freedom.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|