3

I'm actually trying to understand the basic concepts of NASM Assembly in Intel x64 syntax but facing an issue while trying to make a strchr equivalent...

I've been sailing the web to get the maximum information but I can't understand how to compare the current char of a string (like str[i]) with a simple char.

Here is the test main :

#include <stdio.h>

extern char* my_strchr(char*, char);

int     main(void)
{
  char* str;

  str = my_strchr("foobar", 'b');
  printf("%s\n", str);
  return 0;
}

And here is my assembly code :

I assume that rdi is my string and rsi my one-byte data.

my_strchr:
    push    rcx                  ;Save our counter
    xor     rcx, rcx             ;Set it to 0
loop:
    cmp     rdi, byte 0          ;Check the end of string
    jz      end
    cmp     rsi, [byte rdi+rcx]  ;Here is the point ...
    jz      end
    inc     rcx                  ;increment our counter
    jmp     loop
end:
    mov     rax, [rdi+rcx]       ;Are the brackets needed ? Is it equivalent to '&' in C ? 
    pop     rcx
    ret

Gdb gave me this output for the strchr function written in c and so disassembled :

....
cmp    al,BYTE PTR [rbp-0x1c]
....

But mine is actually doing this :

0x400550 <my_strchr>            push   rcx
0x400551 <my_strchr+1>          xor    rcx,rcx
0x400554 <loop>                 cmp    rdi,0x0
0x400558 <loop+4>               je     0x400566 <end>
0x40055a <loop+6>               cmp    rsi,QWORD PTR [rdi+rcx*1+0x0]

Thank you in advance, Hope someone will know

1 Answer 1

3

rdi is a pointer, so cmp rdi, 0 checks for a null pointer. What you meant was cmp byte [rdi + rcx], 0 to check the end of string. Note you need to check the current character so have to add the index obviously.

As for cmp rsi, [byte rdi+rcx] the byte there makes no sense, since you are comparing the whole of rsi which is 8 bytes. That should be cmp sil, [rdi + rcx].

Finally, strchr is supposed to return a pointer so you should change mov rax, [rdi+rcx] to lea rax, [rdi + rcx].

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you ! After your explanation, everything seems clear from now. I've just discovered "lea" instruction and sil (operand ?) how should I know when to use them properly for the future so ?
You can address smaller parts of registers, consult a manual for the names. You use them whenever you need a smaller unit. lea is useful for addressing or some simple arithmetic. You could have done the same with mov rax, rdi; add rax, rcx.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.