strncmp issue

venki kaps venkiece2005 at gmail.com
Tue May 5 07:04:21 UTC 2009


Hi,

I have tested strncmp("abcdefg", "abcdefh", 6) without beq   2f.
It returns zero not -1.

I have checked with conditional assembler but not normal assembler.
The beq 2f  is required for normal assembler.
Right/Wrong?

However also checked with strncmp.c implementation:

int strnncmp(const char *s1, const char *s2, size_t n) {
        if (n == 0)
                return (0);
        do {
                if (*s1 != *s2++)
                        return (*(const unsigned char *)s1 -
                            *(const unsigned char *)--s2);
                if (*s1++ == 0)
                        break;
        } while (--n != 0);
        return (0);
}
the equivalent assembly code:

        cmp     r2, #0
        mov     ip, r0
        beq     2f
1:
        ldrb    r0, [ip, #0]
        ldrb    r3, [r1], #1
        add     ip, ip, #1
        cmp     r0, r3
        bne     3f
        cmp     r0, #0
        beq     2f
        subs    r2, r2, #1
        bne     1b
2:
        mov     r0, #0
        mov     pc, lr
3:
        ldrb    r3, [r1, #-1]
        rsb     r0, r3, r0 /* operand2 - operand1 */
        mov     pc, lr

The results are same.

what could you suggest?

Thanks & Regards,
Venkappa

On Mon, May 4, 2009 at 6:29 PM, Mark Tinguely <tinguely at casselton.net>wrote:

>
> Hi, the propose code by both of you two:
>
> /* if (len == 0) return 0 */
>        cmp     r2, #0
>        moveq   r0, #0
>        moveq   pc, lr
>
> /* ip == last src address to compare */
>        add     ip, r0, r2
> 1:
>        ldrb    r2, [r0], #1
>        ldrb    r3, [r1], #1
>        cmp     ip, r0
>        cmp     r2, #1
>        cmpcs   r2, r3
>        beq     1b
>        sub     r0, r2, r3
>
> That was one of my failed attempts. I to was hoping to not add the branch
> to cut down in cycles. A person has to test every possible call to strncmp.
> This will fail on a positive string length less than strlen length of the
> input strings:
>
> strncmp("abcdefg", "abcdefh", 6)
>
> Will return (-1) str1 < str2 at 6 characters which is wrong.
>
>
> /* if (len == 0) return 0 */
>        cmp     r2, #0
>        moveq   r0, #0
>        moveq   pc, lr
>
> /* ip == last src address to compare */
>        add     ip, r0, r2
> 1:
>        ldrb    r2, [r0], #1
>        ldrb    r3, [r1], #1
>        cmp     ip, r0
>        beq     2f              <- stops in the case where strlen(s1) > len
>        cmp     r2, #1          <- stops thea NULL case, we can't just
> change
>                                   the comparison because below we loop on
>                                   an equality and can end up in a big loop
>
>        cmpcs   r2, r3          <- compare characters.
>        beq     1b
> 2:
>        sub     r0, r2, r3
>
>


More information about the freebsd-arm mailing list