Reputation: 33
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
Upvotes: 3
Views: 4786
Reputation: 58762
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]
.
Upvotes: 3