Assambler problem

I need a assistance for translate a piece of code from Pascal (DOS) to Delphi 3.0 The function is next:

Function Next_CPos
        (Srch_ch:  Char;  Src_str:  String;  Strt_at:  Byte):  Byte;  Assembler;

{This function searches for the next occurence of Srch_ch in Src_str AFTER position Strt_at.  The function returns the offset from the beginning of the string, NOT the offset from Strt_at.
}

Asm  { Function Next_CPos }
                                                     XOR                AX,AX         {        0, AX }                                                        MOV                AL,Strt_at    {        Move position to start at to AL }
LES                DI,Src_str    {        Set ES:DI to start of Src_str }
XOR                CX,CX         {        0 CX }
MOV                CL,[ES:DI]    {        Store length of Src_str in CL }
INC                DI            {        Set ES:DI to first char of Src_str }
MOV                BX,CX         {        Move CX to BX }
SUB                CX,AX         {        Set CX to length of string after Strt_at }
ADD                DI,AX         {        Set ES:DI to char at Strt_at in Src_str }
MOV                AL,Srch_ch    {        Move Srch_ch to AL }
CLD                 {        Clear direction flag }
REPNZ        SCASB         {        Look for character following Strt_at }
JNZ                @NOTFND       {        If not found, jump to end of procedure }
SUB                BX,CX         {        Set BX to position char found in }
JMP                @DONE         {        Jump to end of procedure }
@NOTFND:        XOR                BX,BX         {        Srch_ch not found, set BX to 0 }
@DONE:                MOV                AX,BX         {        Move position found at (BX) to AX }
End;  { Function Next_CPos }
danutiAsked:
Who is Participating?
 
EpsylonConnect With a Mentor Commented:
This should be it:

Function Next_CPos (Srch_ch:  Char;  Src_str:  String;  Strt_at:  Byte):  Byte;
var i: Integer;
begin
  i := Strt_at;
  while (i <= Length(Src_str)) and (Src_str[i] <> Srch_ch) do
    Inc(i);
  if i > Length(Src_str) then
    Result := 0
  else
    Result := i;
end;

0
 
EpsylonCommented:
Well, if it should find the first 'Srch_ch' AFTER 'Strt_at' then change the line

  i := Strt_at;

to

  i := Strt_at + 1;


Cheers,

Epsylon.
0
 
simonetCommented:
Listening...
0
Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

 
EpsylonCommented:
You have many ears, Alex  :o)
0
 
simonetCommented:
Hehehe! I'll stop using "listening" on questions I follow. From now on I'll use "monitoring" or "following". You guys never stop joking about the "listening" thing. ;|

Alex
0
 
viktornetCommented:
here...

Function Next_CPos (Srch_ch:  Char;  Src_str:  String;  Strt_at: Integer) :  Integer;
begin
  result := Pos(Srch_ch, Copy(Src_str, Strt_at, Length(Src_str)));
end;

and you can use it like so...

Caption := IntToStr(Next_CPos('a', Edit1.Text, 1));

..-=ViKtOr=-..
0
 
EpsylonCommented:
A very short one, Viktor, but slow and memory consuming when you want to search very large strings. The Copy function should not be used then.

Eps.
0
 
viktornetCommented:
hehe not true,,,, first my method uses assembler... great... second yours uses a loop which needs a comparison on each iritation of the loop... bad... you've another comparison in there which slows it down a LOT especially if called many times in another loop... it's not memory consuming at all... Delphi's been created in a way that the memory manager is smart and knows what to do when this occurs...
0
 
viktornetCommented:
btw, Epsylon, if you don't like that one you could try the following which is EXTREMELY fast...

Function Next_CPos1 (Srch_ch:  Char;  Src_str:  PChar;  Strt_at: Integer) :  Integer;
begin
  Result := Pos(Srch_ch, PChar(Src_Str+Strt_at-1));
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
     Caption := IntToStr(Next_CPos('a', PChar(Edit1.Text), 1));
end;

..-=ViKtOr=-..
0
 
EpsylonCommented:
> hehe not true

True! The Copy function copies the whole string from index 'Strt' until the end.


> second yours uses a loop which needs a comparison on each iritation of the loop

What do you think the Pos function does?


Eps.
0
 
viktornetCommented:
or even this...if you want to use a String and simply typecast it within the function for less confusion...

Function Next_CPos1 (Srch_ch:  Char;  Src_str:  String;  Strt_at: Integer) :  Integer;
      begin
        Result := Pos(Srch_ch, PChar(PChar(Src_Str)+Strt_at-1));
      end;

      procedure TForm1.Button1Click(Sender: TObject);
      begin
           Caption := IntToStr(Next_CPos('a', Edit1.Text, 1));
      end;

..-=ViKtOr=-..
0
 
EpsylonCommented:
And the second comparison you talk about must be 'hidde' in the Pos function too.
0
 
viktornetCommented:
>>What do you think the Pos function does?
well yeah... didn't think of that... anyway... take a look at the new function... cant even compare it with yours in speed ;)
0
 
viktornetCommented:
plus ur code can be optimized...
0
 
EpsylonCommented:
Haha, that function does not work correctly   :o)
0
 
viktornetCommented:
well it does on my computer....
0
 
viktornetCommented:
opps... i feel so embarassed ;o))

hehe... I completely forgot that the Strt_at could be a a different value than 1 and didnt even test that ;-))

this one works alright....

Function Next_CPos(Srch_ch:  Char;  Src_str:  String;  Strt_at: Integer) :  Integer;
begin
  Result := Pos(Srch_ch, PChar(PChar(Src_Str)+Strt_at-1));
  if Result <> 0 then Inc(Result, Strt_at-1);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  Caption := IntToStr(Next_CPos('a', Edit1.Text, 3));
end;
0
 
danutiAuthor Commented:
Thanks Epsylon's for your answer. It is fastest and I use it in my program.
If I can help you, please ask me.
Thanks again.
0
All Courses

From novice to tech pro — start learning today.