Home > Software design >  Return a pointer at a specific position - Assembly
Return a pointer at a specific position - Assembly

Time:02-21

I am a beginner in Assembly and i have a simple question. This is my code :

BITS 64                     ; 64−bit mode
global strchr               ; Export 'strchr'

SECTION .text           ; Code section
strchr:
    mov rcx, -1
.loop:
    inc rcx
    cmp byte [rdi rcx], 0
    je exit_null
    cmp byte [rdi rcx], sil
    jne .loop
    mov rax, [rdi rcx]
    ret

exit_null:
    mov rax, 0
    ret

This compile but doesn't work. I want to reproduce the function strchr as you can see. When I test my function with a printf it crashed ( the problem isn't the test ). I know I can INC rdi directly to move into the rdi argument and return it at the position I want. But I just want to know if there is a way to return rdi at the position rcx to fix my code and probably improve it.

CodePudding user response:

Your function strchr seems to expect two parameters:

  1. pointer to a string in RDI, and
  2. pointer to a character in RSI.

Register rcx is used as index inside the string? In this case you should use al instead of cl. Be aware that you don't limit the search size. When the character refered by RSI is not found in the string, it will probably trigger an exception. Perhaps you should test al loaded from [rdi rcx] and quit further searching when al=0.

If you want it to return pointer to the first occurence of character inside the string, just
replace mov rax,[rdi rcx] with lea rax,[rdi rcx].

CodePudding user response:

Your code does the following:

char* strchr ( char *p, char x ) {
   int i = -1;
   while ( p[i] != '\0' ) {
      i  ;
      if ( p[i] == x )
          return p[i];
   }
   return null;
}

As @vitsoft says, your intention is to return a pointer, but in the first return statement are returning a single character.


It is unusual to increment in the middle of the loop.  It is also odd to start the index at -1.  On the first iteration, the loop continue condition looks at p[-1], which is not a good idea, since that's not part of the string you're being asked to search.  If that byte happens to be the nul character, it'll stop the search right there.

If you waited to increment until both tests are performed, then you would not be referencing p[-1], and you could also start the index at 0, which would be more usual.


You might consider suggest capturing the character into a register instead of using a complex addressing mode three times.

Further, you could advance the pointer in rdi and forgo the index variable altogether.

Here's that in C:

char* strchr ( char *p, char x ) {
    for(;;) {
        char c = *p;
        if ( c == '\0' )
            break;
        if ( c == x )
            return p;
        p  ;
   }
   return null;
}

CodePudding user response:

Thanks to your help, I finally did it ! Thanks to the answer of Erik, i fixed a stupid mistake. I was comparing str[-1] to NULL so it was making an error. And with the answer of vitsoft i switched mov to lea and it worked ! There is my code :

strchr:
    mov rcx, -1
.loop:
    inc rcx
    cmp byte [rdi rcx], 0
    je exit_null
    cmp byte [rdi rcx], sil
    jne .loop
    lea rax, [rdi rcx]
    ret

exit_null:
    mov rax, 0
    ret
  • Related