'How to find characters in a string Assembly x86?

I'm trying to rewrite the C code below in Assembly x86

int myFn( char * v, char c, int size ) {
  int i;
  for(i=0; i < size; i++ )
    if( v[i] == c )
      return i;
  return -1;
}

I've tried to use this code in x86:

myFn:
  mov esi, 0
  mov ebx, [esp + 8]
  mov ecx, [esp + 12]

  FOR:
    mov eax, -1
    cmp esi, [esp + 4]
    jge ENDFOR

    cmp [ecx + esi], ebx
    je EQUAL

    inc esi
    jmp FOR
  
  EQUAL:
    mov eax, [esi]
  
  ENDFOR:

  ret

I've also created this program to test the function:

section .data
  fmt: db "strfind: %d", 10, 0
  str: db "test", 0

section .text
  global main
  extern printf

main:
  mov eax, 's'
  mov ebx, 4

  push str
  push eax
  push ebx
  call myFn
  add esp, 12

  push eax
  push fmt
  call printf
  add esp, 8

  ret

myFn:
  mov esi, 0
  mov ebx, [esp + 8]
  mov ecx, [esp + 12]

  FOR:
    mov eax, -1
    cmp esi, [esp + 4]
    jge ENDFOR

    cmp [ecx + esi], ebx
    je EQUAL

    inc esi
    jmp FOR
  
  EQUAL:
    mov eax, [esi]
  
  ENDFOR:

  ret

I'm getting Segmentation Fault error or the wrong result when trying to test it. I believe the problem is when comparing the character of the string with the character I want to find



Solution 1:[1]

ASCII chars are all 8 bits so you do not need 32 bit registers to store the chars. You should use 8 bit registers like al to hold the char. Below is a program that I wrote in nasm 64-bit that works fine.

global    _start

section   .data
str:  db  "test", 0    

section   .text

_start:
    mov al, 's'
    mov bl, 4
    mov cl, 0

    mov rsi, str

; iterate over the string
L1:
    cmp [rsi], al
    je ENDL1 ; if found, jmp to ENDL1 label
    inc rsi
    inc cl
    cmp cl, 4
    jbe L1
    mov cl, -1 ; if not found


ENDL1:
    xor rax, rax ; set rax register to 0
    mov al, cl ; rax equal index in string i.e rax = 0x2

The reason you are getting the SEGMENTATION FAULT is probably because you didn't use the exit syscall at the end of the program. To fix this, write the following at the end of your main function:

; exit syscall
mov rax, 60                 ; system call for exit
xor rdi, rdi                ; exit code 0
syscall

Adjust the code for 32-bit mode as per your requirement.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Taimoor Zaeem