pseudo code:
; si = input string
di = output string
if 0 == [si] jmp NoNumberFound
NextNumberLoop:
rax = 0
ReadLoop:
bl = [si] & inc si
if 0 == bl jmp LastNumberFound
if ',' == bl jmp CommaFound
rax = rax*10 + (bl-'0') ; extend bl to 64b of course
jmp ReadLoop
CommaFound:
call StoreNumberPlusOne
[di]=',' & inc di
jmp NextNumberLoop
LastNumberFound:
call StoreNumberPlusOne
NoNumberFound:
[di]='0'
output resulting string and exit.
StoreNumberPlusOne:
inc rax (number+1)
print decimal formatted rax to [di] + make di point after it
ret
(di/si pointer on 64b platform are of course rsi/rdi, etc... it's just pseudo code showing algorithm, not to be taken literally)
Other option is to do it in string itself without parsing numbers.
Allocate large enough buffer for resulting string (if you put input as n
times 9
, the output buffer will be almost twice as long as input buffer, containing n
times 10
).
Copy input string to outputBuffer, and have the pointer ptr
at the last character of it.
doIncrement = true
while (outputBuffer <= ptr) {
if ',' == [ptr] {
if doIncrement {
move by 1 byte further everything from ptr+1 onward:
in ASM you can do that by simple REP MOVSB, but as the
source overlap destination, make sure you use STD (DF=1)
together with end pointers.
[ptr+1] = '1'
}
doIncrement = true
} else {
; [ptr] should be between '0' to '9' (for valid input)
if doIncrement {
++[ptr]
if '9'+1 == [ptr] {
[ptr] = '0'
} else {
doIncrement = false
}
}
}
--ptr;
}