-2

How do I split a string by , delimeter in assembly AT&T?

This is the string I have: 6, 3, 2431, 7, 9, 1221

I want to add 1 to all the numbers between the ,.

Result should be: 7, 4, 2432, 8, 10, 1222

I'm working with ubuntu14 - 64bit, intel cpu and GAS compiler

splunk
  • 6,435
  • 17
  • 58
  • 105
  • 2
    The best way to do this is to write some code that will scan through the string for commas, convert the ASCII numbers into a numeric value and add whatever you want to them. If you're asking us to write this code for you, you're in the wrong place. – David Hoelzer Jun 20 '16 at 13:55
  • 1
    Is this comma delimited “string” in a source file? Passed as a pointer or on the stack? Size and type of a string element? What have you tried? – jolati Jun 20 '16 at 14:27

1 Answers1

1

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;
}
Ped7g
  • 16,236
  • 3
  • 26
  • 63
  • 1
    Since x86-64 is guaranteed to have SSE2 available, I might be inclined to use `pcmpeqb` / `pmovmskb` / `bsf` to find the position of the next `,`. You can even use SSE for string->integer (`pmaddwd` with a vector of 1, 10, 100, ... place-values). You can do even more cool stuff with if SSSE3 pshufb is available, like [converting an IPv4 dotted-quad string to an integer](http://stackoverflow.com/a/31683632/224132). – Peter Cordes Jun 21 '16 at 07:04