To the ineffable ALL,

Believe it or not, it's easy to subtract two decimal ASCII strings in DWORD gulps without converting each byte into BCD, or the string into binary, or any other such nonsense. It's four bytes for each pass through the routine. What's more, the difference remains in ASCII. The length of the two strings to be added is limited only by the available memory. Don't believe it? Then look at the code below for one DWORD. Naturally, the method can be extended to any length you want. You can see an example of that if you download the ZIP. The catch is that there is no checking for bogus non decimal characters in the string. That means there cannot be any nulls, periods, commas, dollar or pound signs, or any other punctuation. It's hard to describe in the code notes how it works, but it becomes clearer if you run a few examples with a good debugger and see those registers subtract the way you want them to. Try it, you will probably like it. Anybody want to tackle multiplication? Ratch



;EDX = 1 if carry flag from previous subtraction present, else 0
MOV EAX,DWORD PTR [SUB1+ESI]
BSWAP EAX ;&%@#*$ Intel to hell, need to switch it around from little endian
SUB EAX,EDX ;subtract the carry flag
MOV ECX,DWORD PTR [SUB2+ESI]
BSWAP ECX ;&%@#*$ Intel to hell, need to switch it around from little endian
SUB EAX,ECX ;subtract the second number from the first
SETC DL ;store carry flag from present subtraction
;we just did the subtraction, now comes the extraction
;retrieve the ASCII decimal digits
MOV ECX,EAX
AND ECX,0F0F0F0F0H ;mask out all the sign extensions
SUB EAX,ECX ;remove the sign extensions for each digit
SHR ECX,4 ;switch the mask over one nibble
AND ECX,006060606H ;adjust mask for sign extensions only
SUB EAX,ECX ;subtract the 6 from HEX values to get 9 decimal or less
OR EAX,030303030H ;only decimal numbers left in each byte, fill in with '0's to make ASCII numeric
Posted on 2004-02-16 01:42:03 by Ratch