News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

text to number and vice a versa

Started by ninjarider, September 23, 2005, 03:34:49 PM

Previous topic - Next topic

ninjarider

the string is stored in CommandLine which is at address ds:si. cx stores the current value of the string

Value:
lodsb
mov bl, al
and bl, 30h
cmp bl, 30h
jne Value
and al, 0fh
add cx, al
jmp Value

im pretty sure this isn't the best way to convert to a number, and i have no idea how to convert back. any suggestions the above code and the numeric to text conversions

Tedd

There are a number of ways to do it, however I don't think you've thought that one through properely. Try an example string and work through it by hand to see what it really does :wink

A simple approach is: (using "1234" as example string)
- get digit (leftmost = "1")
- convert to value, rather than ascii digit (sub 31h,30h = 1)
- add to answer (answer = 1)
- move onto next digit ("2")
- is it the end of the string? (null-terminator?) -- exit if so
- answer = answer * 10
- convert, add, etc - for the rest of the string

(The above pseudo code could be arranged better, but it's only meant to demonstrate how to do it.)

There are a few issues to consider, such as finding a non-digit, but let's keep it simple first :bg
No snowflake in an avalanche feels responsible.

ninjarider

tedd,
  thnx for noticing that theres no multiplication by ten, and testing for terminating string.

instead of

mov bl, al
and bl, 30h
cmp bl, 30h

is there anything that will test for the 0011_0000 bit pattern even if bl is 0111_0100

gabor

It is not 100% clear for me what you want to achieve.

My guess is to test for a pattern like this:
- You want to detect 00110000b patterns.
For example when bl=00110010b or bl=00110011b or bl=01110010b you want the pattern test to be true.

This can simply be done by the test instruction.


        mov  bl,00110011b
...
        test bl,00110000b
        jz @_no_match
; match
...
@_no_match:
...


The test instruction is an and instruction that does not change the operands value, in this example the value of bl. So, when the result of the logical and is 0 (no pattern match) the Z flag is set.

I hope I helped.

Greets, Gábor


Tedd

"test bl,30h" is a nice idea, but slightly wrong - for two reasons.

1. it will unset ZF if the result is zero, and set otherwise. Meaning values 10h....20h....30h....3fh will all trigger.
2. the idea of testing those bits is because the digits are 30h..39h -- try the same thing with values such as 70..39h and any other numbers which also have those bits set. You have no way to distinguish.

You do need to do the two checks: one for above and one for below.
However, you can roll them into one :green
mov bl,al
sub bl,30h         ;anything less than a digit will become negative; digits will be 0-9; anything above is not a digit
cmp bl,9           ;if above 9, it's not a digit
ja @not_a_digit    ;this is unsigned comparison, so negatives are treated as larger positives

No snowflake in an avalanche feels responsible.