Kings man
Kings man

Reputation: 17

How to implement strncmp in NASM

I am trying to implement my own strncmp in asm. Here is the NASM code:

section .text

global my_strncmp

my_strncmp:
    mov rcx, 0; using rcx like counter
.next:
    cmp rdx, rcx ; i think this comparing doesn't work (i have no idea with it) 
    je .return_0

    mov dh, byte [rdi]
    mov dl, byte [rsi]

    cmp byte [rdi], 0
    je .return_0 ;string ending
    
    cmp byte [rsi], 0
    je .return_0 ;string ending

    inc rcx
    inc rsi
    inc rdi

    cmp dh, dl
    je .next ; the loop continues until the string ends 
    jl .return_1
    jg .retrun_2

.return_0:
    mov rax, 0
    ret

.return_1:
    mov rax, 1
    ret

.retrun_2:
    mov rax, -1
    ret

And I am using this simple C code to run NASM:

int main(){
    printf("%d\n", my_strncmp("string2", "string1", 3));
}

My strncmp actually works like ordinary strcmp (from C std. library), it's just not jumping to .return_0 label from line 8 which reads cmp rdx, rcx.

Upvotes: 0

Views: 179

Answers (1)

Sep Roland
Sep Roland

Reputation: 39621

  • The cmp rdx, rcx can't work because the rest of the code erroneously modifies part of the RDX register (mov dh, byte [rdi] and mov dl, byte [rsi] both touch parts of RDX).
    You don't need to use 2 registers to implement the 'compare at most' part of the task. Just decrement the 3rd argument and return equal once the count runs out.
  • Don't compare the characters using the signed condition. Treat them unsigned using jb and ja (replacing jl and jg).
my_strncmp:
        xor   eax, eax        ; Remains zero throughout the loop
.Cont:  sub   rdx, 1
        jb    .EQ             ; Count ran out
        movzx ecx, byte [rsi]
        cmp   [rdi], cl
        jb    .LT
        ja    .GT
        inc   rdi
        inc   rsi
        test  cl, cl
        jnz   .Cont
.EQ:    ret                   ; RAX=0
.LT:    dec   rax
        ret                   ; RAX=-1
.GT:    inc   eax
        ret                   ; RAX=1

Upvotes: 1

Related Questions