.file "ustrlen.c" .section .rodata .align 4 .type submagic, @object .size submagic, 4 submagic: .long 16843009 .align 4 .type andmagic, @object .size andmagic, 4 andmagic: .long -2139062144 .text .globl ustrlen .type ustrlen, @function ustrlen: pushl %ebp movl %esp, %ebp movl 8(%ebp), %ecx movl %ecx, %eax ;;;; Check individual characters up to the word boundary. .L2: testb $3, %al je .L3 cmpb $0, (%eax) je .L27 incl %eax testb $3, %al je .L3 cmpb $0, (%eax) je .L27 incl %eax testb $3, %al je .L3 cmpb $0, (%eax) je .L27 ;;;; Last two checks where swapped to prevent this from becoming a jump. incl %eax cmpb $0, (%eax) je .L27 testb $3, %al jne .L2 .L3: movl %eax, %edx ;;;; Start checking string a longword at a time. .L26: ;;;; First if; see if any high bits where set after subtracting. ;;;; We keep the result of the subtraction. movl (%edx), %eax subl $16843009, %eax addl $4, %edx testl $-2139062144, %eax je .L26 ;;;; A high bit was set; see if it was changed by the subtraction. xorl -4(%edx), %eax testl $-2139062144, %eax je .L26 ;;;; Guess not; start checking characters individually leal -4(%edx), %eax cmpb $0, -4(%edx) je .L27 incl %eax cmpb $0, (%eax) je .L27 incl %eax cmpb $0, (%eax) je .L27 ;;;; If the previous checks failed, it has to be the last one. incl %eax .L27: subl %ecx, %eax popl %ebp ret .size ustrlen, .-ustrlen .ident "GCC: (GNU) 3.3.2 20030812 (Debian prerelease)"