Find all the digits in a string S is a given character string, then I have to find all the digits characters of S. Did I make it unnecessarily complicated?
bits 32

global start        

extern exit
import exit msvcrt.dll

segment data use32 class=data
    s db '+', 'r', '0', '8', '8', '1', 'i', '5'
    len equ $ - s
    digits db '012345789'
    d times len db 0
segment code use32 class=code
    start:
        mov ecx, len
        
        mov esi,0
        mov ebx,0
        
        jecxz end_prog
        
        repeat_this:
            push ecx
            mov al, [s + esi]
            mov ecx, 10
            mov edi, digits
            find:
                scasb
                jz found
            loop find
            
            jmp next
            
            found:
                mov edi, ebx
                inc ebx
                mov [d + edi], al
            
            next:   
                inc esi
                pop ecx
        loop repeat_this
        
        end_prog:
        
        push    dword 0
        call    [exit]
Did I make it unnecessarily complicated?


You can replace
find:
  scasb
  jz    found
  loop  find
  jmp   next

by the simpler
  repne scasb
  jne   next

The use of the SCASB instruction here depends on the direction flag DF being in the clear state (CLD). It is a safe assumption that this will be the case. Nonethesless prudent programmers will at least at program start include one CLD instruction.
If ever you find that you need to reverse the direction for the string primitives by the use of STD, you should always issue a restoring CLD as soon as possible (once the string operation has finished). Why is this? Well, just as you can expect the direction flag to be clear, any library functions that your program invokes expect the same thing. During normal program execution DF=0 is almost true 100% of the time. See.

No need to use the extra register EDI in:
mov   edi, ebx
inc   ebx
mov   [d + edi], al

Just write:
mov   [d + ebx], al
inc   ebx


The digits have well-known ASCII codes. Finding a digit is just a matter of comparing AL with the range 48 to 57. I find scanning that digits string a bit overkill, although at times that could be a good way. When the character codes aren't contiguous.
  mov   ecx, len
  jecxz end_prog
  xor   esi, esi
  xor   ebx, ebx
repeat_this:
  mov   al, [s + esi]
  cmp   al, '0'
  jb    next
  cmp   al, '9'
  ja    next
  mov   [d + ebx], al
  inc   ebx
next:   
  inc   esi
  loop  repeat_this

Clearing a register is best done using XOR &lt;reg&gt;,&lt;reg&gt;.



This shorter version uses the string primitives and avoids using the slow LOOP instruction:
    mov   ecx, len
    mov   esi, s
    mov   edi, d
    jmp   next
  repeat_this:
    lodsb
    cmp   al, '0'
    jb    next
    cmp   al, '9'
    ja    next
    stosb
  next:
    sub   ecx, 1  
    jnb   repeat_this