Hi,
inflater wrote:How I can convert decimal number to hexadecimal and vice-versa?
I'll assume you want to convert BCD to an integer and back again. For e.g. "00010010b" (BCD for 12) becomes "00001100b" (binary for 12).
If you can use the FPU and the BCD is 20 digits (zero extended), you can do something like this:
Code: Select all
fbld tword [address_of_BCD]
fistp qword [address_of_binary]
Code: Select all
fild qword [address_of_binary]
fbstp tword [address_of_BCD]
If you can't do this, then you could do generic routines like this:
Code: Select all
int convert_BCD_to_int(void *address) {
unsigned char temp;
int multiplier = 1;
int value;
for( i = 0; i < length; i++) {
temp = *(unsigned char*)address;
address++;
value = value + multiplier * (temp & 0x0F);
multiplier = multiplier * 10;
value = value + multiplier * (temp >> 4);
multiplier = multiplier * 10;
}
return value;
}
void convert_int_to_BCD(int value, void *address) {
unsigned char temp;
int i;
while(value != 0) {
temp = value % 10
value = value / 10;
temp = temp | ((value % 10) << 4);
value = value / 10;
((unsigned char*)address)[i++] = temp;
}
while(i < length) {
((unsigned char*)address)[i++] = 0;
}
}
This is incredibly slow though. For the CMOS you know each value fits in a byte and is only 2 digits. In this case you could do something like this:
Code: Select all
unsigned char convert_BCD_to_byte(unsigned char BCD) {
return ((BCD >> 4) * 10) + (BCD & 0x0F);
}
unsigned char convert_byte_to_BCD(unsigned char value) {
return (value % 10) | ( (value / 10) << 4);
}
Of course if you want the fastest possible method, you might consider using tables with 256 entries:
Code: Select all
unsigned char convert_BCD_to_byte(unsigned char BCD) {
return BCD_to_byte_converstion_table[BCD];
}
unsigned char convert_byte_to_BCD(unsigned char value) {
return byte_to_BCD_converstion_table[value];
}
This is fast, but predefining those 256 entry tables is a pain. Another alternative would be:
Code: Select all
convert_BCD_to_byte:
mov ah,al
shr ah,4
and al,0x0F
aad
or al,ah
ret
convert_byte_to_BCD:
aam
shl ah,4
or al,ah
ret
This is probably the fastest way that doesn't involve tables (as long as input values are valid and are in range).
Cheers,
Brendan