2016-06-20 12 views
-2

Wie teile ich eine Zeichenfolge durch , Delimeter in Assembly AT & T?Split String Assembly AT & T

Dies ist die Zeichenfolge ich habe: 6, 3, 2431, 7, 9, 1221

I 1 bis alle Zahlen zwischen den , hinzufügen möchten.

Ergebnis sollte sein: 7, 4, 2432, 8, 10, 1222

Ich arbeite mit ubuntu14 - 64bit, Intel-CPU und GAS Compiler

+2

Der beste Weg, dies zu tun ist, einen Code zu schreiben, der die Zeichenfolge nach Kommas scannt, die ASCII-Zahlen in einen numerischen Wert umwandelt und fügt, was auch immer Sie wollen. Wenn Sie uns bitten, diesen Code für Sie zu schreiben, sind Sie an der falschen Stelle. –

+1

Ist diese durch Kommas getrennte "Zeichenfolge" in einer Quelldatei? Als ein Zeiger oder auf dem Stapel übergeben? Größe und Typ eines String-Elements? Was hast du probiert? – jolati

Antwort

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 Zeiger auf 64b Plattform sind natürlich rsi/rdi, etc ... es ist nur Pseudo-Code zeigt Algorithmus, nicht wörtlich zu nehmen)


Eine andere Option ist es in String selbst zu tun, ohne Zahlen zu analysieren.

Puffer zuweisen groß genug für resultierende Zeichenfolge (wenn Sie Eingabe als n mal 9 setzen, wird der Ausgangspuffer als Eingangspuffer fast doppelt so lang sein, mit n mal 10).

Kopieren Sie die Eingabezeichenfolge in outputBuffer, und setzen Sie den Zeiger ptr auf das letzte Zeichen davon.

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; 
} 
+1

Da x86-64 garantiert SSE2 zur Verfügung hat, könnte ich 'pcmpeqb' /' pmovmskb'/'bsf' verwenden, um die Position des nächsten', 'zu finden. Sie können SSE sogar für string-> integer ('pmaddwd' mit einem Vektor von 1, 10, 100, ... place-values) verwenden. Sie können noch mehr coole Sachen machen, wenn SSSE3 pshufb verfügbar ist, wie zB [Konvertieren einer IPv4-Zeichenkette in eine ganze Zahl] (http://stackoverflow.com/a/31683632/224132). –