procedure __SKRASMTEST(ValueAddr : dword; Len : byte; var Str : string);
// ====================================================================================================================
//
// procedure __SkrASMConvertDecimalToStr(Value : dword; Len : byte; var Str : string);
//
// This routine converts a 32 bit value <Value> to a printable string <Str>. Length is 10
// characters. <Str> is padded with zeros. This routine uses substraction rather than division.
// ====================================================================================================================
begin
asm
addu R8,R26,R27
lui R2,hi_addr(_Tenthx10) // get address of highest subtractor
ori R2,R2,lo_addr(_Tenthx10)
lw R7,0(R25) // get value at address
NewDigit: // next digit
or R6,R0,R0 // reset counter for ASCII character
OnceMore: // new round checking current digit
lw R4,0(R2) // get subtractor from array
subu R7,R7,R4 // subtract this power
bltz R7,ZeroDigit // if negative result of subtraction, digit = 0 (this power is bypassed)
NOP
slt R5,R7,R4 // if R5 = 1, end of round reached zero, we got the digit
addiu R6,R6,1 // update ASCII counter
bgtz R5,OtherDigit // test if R5 = 1, if so end loop
NOP
b OnceMore // loop
NOP
ZeroDigit:
addu R7,R7,R4 // correcting remaining value
OtherDigit:
addiu R6,R6,48 // convert counter to ASCII
sb R6,0(R27) // store character to Str
addiu R2,R2,4 // pointer to next power subtractor
addiu R27,R27,1 // next address in resulting string
bne R27,R8,NewDigit // check if we are done
NOP
sb R0,0(R27) // add string terminator
end;
end;
This routine do sequential subtractions until each power of 10 is zero, the sequence is counted and will be equal to actual digit. If below zero, the actual digit is zero. This works nicely and is faster than division. The problem occurs when MSB is set to '1', also a negative number that covers 0xAFFFFFFF to 0xFFFFFFFF. Has tried to use unsigned aritmetics for the subtraction (subu) but does not work since the result still is negative. Any solution?
User contributions licensed under CC BY-SA 3.0