[Back to STRINGS SWAG index] [Back to Main SWAG index] [Original]

    var
      s1, s2: string;

    function RPos( var str1, str2: string ): byte; assembler;
      { returns position of the last occurrence of str1 in str2 }
      { return value in AX }
      { str1 - string to search for }
      { str2 - string to search in  }
    asm
            STD              { string operations backwards               }
            LES   DI,Str2    { load in ES:DI pointer to str2             }
            XOR   CH,CH      { clear CH                                  }
            MOV   CL,[DI]    { length str2 --> CX                        }
            AND   CX,CX      { length str2 = 0?                          }
            JZ    @Negatief  { length str2 = 0, nothing to search in     }
            ADD   DI,CX      { make DI point to the last char of str2    }
            LDS   SI,Str1    { load in DS:SI pointer to str1             }
            XOR   AH,AH      { clear AH                                  }
            MOV   AL,[SI]    { load in AX length str1                    }
            AND   AL,AL      { length str1 = 0?                          }
            JZ    @Negatief  { length str1 = 0, nothing to search for    }
            ADD   SI,AX      { make SI point to the last char of str1    }
            MOV   AH,AL      { length str1 --> AH                        }
            DEC   AH         { last char need not be compared again      }
            LODSB            { load in AL last character of str1         }
    @Start:
      REPNE SCASB            { scan for next occurrence 1st char in str2 }
            JNE   @Negatief  { no success                                }
            CMP   CL,AH      { length str1 > # chars left in str2 ?      }
            JB    @Negatief  { yes, str1 not in str2                     }
            MOV   DX,SI      { pointer to last but 1 char in str1 --> DX }
            MOV   BX,CX      { number of chars in str2 to go --> BX      }
            MOV   CL,AH      { length str1 --> CL                        }
       REPE CMPSB            { compare until characters don't match      }
            JE    @Positief  { full match                                }
            SUB   SI,DX      {                                           }
            NEG   SI         { prev. SI - current SI = # of chars moved  }
            ADD   DI,SI      { reconstruct DI                            }
            MOV   SI,DX      { restore pointer to 2nd char in str1       }
            MOV   CX,BX      { number of chars in str2 to go --> BX      }
            JMP   @Start     { scan for next occurrence 1st char in str2 }
    @Negatief:
            XOR   AX,AX      { str1 is not in str, result 0              }
            JMP   @Exit
    @Positief:
            INC   BL
            SUB   BL,AH      { start position of str1 in str2            }
            MOV   AL,BL      { in AL                                     }
            XOR   AH,AH      { clear AH                                  }
    @Exit:                   { we are finished. }
    end  { RPos };

    begin
      s1 := ParamStr( 1 );
      s2 := ParamStr( 2 );
      writeln( RPos( s1, s2 ) );
    end.

    {
    If a '#' (shift-3) appears in the assembler source code, please replace
    that by a at-sign (shift-2).
    }

[Back to STRINGS SWAG index] [Back to Main SWAG index] [Original]