5
\$\begingroup\$

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]
\$\endgroup\$
1
  • \$\begingroup\$ Don't forget that your title should only state the task accomplished by the code and nothing else. I also recommend you to add more information about your code in the body to help reviewers \$\endgroup\$
    – user228914
    Nov 7, 2020 at 9:00

1 Answer 1

5
\$\begingroup\$

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 <reg>,<reg>.


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
\$\endgroup\$
2
  • 1
    \$\begingroup\$ Good review! It might be worth commenting on the Direction Flag and what are and are not safe assumptions about its state. \$\endgroup\$
    – Edward
    Nov 7, 2020 at 20:09
  • 1
    \$\begingroup\$ You can also range-check more efficiently with lea edx, [eax-'0'] / cmp dl, 9 / ja next. Of course if you care about performance on modern CPUs you'd use movzx eax, [esi] / inc esi to load, instead of letting lodsb merge into the old EAX value. (Why doesn't GCC use partial registers?). lodsb and stosb aren't fast in general. \$\endgroup\$ Nov 19, 2020 at 19:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.