strlen()

07/06/2010 - 22:04 von Markus Wichmann | Report spam
Hi all,

ich bin gerade dabei, strlen() in Assembler zu schreiben (ich brauche es
in einer Applikation, die ansonsten keine libc braucht, und nur dafür
wollte ich sie nicht einlinken).

Natürlich kenne ich den Ansatz mit "repne scasb", aber ich wollte
String-Instruktionen vermeiden (weil schnarchlahm). Ich hab im Internet
schlaue Tricks mit logischem Und, XOR und Addition gefunden, aber die
hat nicht funktioniert (von Hand durchgerechnet, hat ein String-Ende
nicht gefunden).

Kennt da jemand etwas?

Ich meine, OK, es geht natürlich

.outer_loop:
mov rax, [rcx]
mov rbx, 0ffh
.test_loop:
test rax, rbx
jz .ende
shl rbx, 8
jnz .test_loop
add rcx, 8
jmp .outer_loop
.ende: ; String-Ende gefunden, das denke ich mir dann morgen aus

Aber da ist ja branching ohne Ende drin, inklusive verschachtelter
Schleife. Geht das schöner?
 

Lesen sie die antworten

#1 Jan Seiffert
08/06/2010 - 00:21 | Warnen spam
Markus Wichmann schrieb:
Hi all,

ich bin gerade dabei, strlen() in Assembler zu schreiben (ich brauche es
in einer Applikation, die ansonsten keine libc braucht, und nur dafür
wollte ich sie nicht einlinken).

Natürlich kenne ich den Ansatz mit "repne scasb", aber ich wollte
String-Instruktionen vermeiden (weil schnarchlahm). Ich hab im Internet
schlaue Tricks mit logischem Und, XOR und Addition gefunden, aber die
hat nicht funktioniert (von Hand durchgerechnet, hat ein String-Ende
nicht gefunden).

Kennt da jemand etwas?

Ich meine, OK, es geht natürlich

.outer_loop:
mov rax, [rcx]
mov rbx, 0ffh
.test_loop:
test rax, rbx
jz .ende
shl rbx, 8
jnz .test_loop
add rcx, 8
jmp .outer_loop
.ende: ; String-Ende gefunden, das denke ich mir dann morgen aus

Aber da ist ja branching ohne Ende drin, inklusive verschachtelter
Schleife. Geht das schöner?



000000a0 <strlen_x86>:
a0: 8b 4c 24 04 mov 0x4(%esp),%ecx
a4: 89 ca mov %ecx,%edx
a6: 83 e1 03 and $0x3,%ecx
a9: 83 e2 fc and $0xfffffffc,%edx
ac: c1 e1 03 shl $0x3,%ecx
af: 51 push %ecx
b0: 8b 0a mov (%edx),%ecx
b2: 8d 81 ff fe fe fe lea -0x1010101(%ecx),%eax
b8: f7 d1 not %ecx
ba: 21 c8 and %ecx,%eax
bc: 59 pop %ecx
bd: 25 80 80 80 80 and $0x80808080,%eax
c2: d3 e8 shr %cl,%eax
c4: d3 e0 shl %cl,%eax
c6: 85 c0 test %eax,%eax
c8: 75 15 jne df <strlen_x86+0x3f>
ca: 01 ca add %ecx,%edx
cc: 8b 0a mov (%edx),%ecx
ce: 8d 81 ff fe fe fe lea -0x1010101(%ecx),%eax
d4: f7 d1 not %ecx
d6: 21 c8 and %ecx,%eax
d8: 25 80 80 80 80 and $0x80808080,%eax
dd: 74 eb je ca <strlen_x86+0x2a>
df: 0f bc c0 bsf %eax,%eax
e2: c1 e8 03 shr $0x3,%eax
e5: 01 d0 add %edx,%eax
e7: 2b 44 24 04 sub 0x4(%esp),%eax
eb: c3 ret

Hmm, ich weiss nur grad nicht ob die funzt, hab die schon lange nicht mehr
getested...
Willst du noch die SSE, SSE2, SSE4.2 Version? Da weiss ich das die gehen ;)
Oder fuer x86_64?

Gruss
Jan

“There is nothing so useless as doing efficiently that which should
not be done at all.”
— Peter Drucker

Ähnliche fragen