Solved

Assembly Problem

Posted on 2006-11-13
19
298 Views
Last Modified: 2010-08-05
procedure TForm1.Button2Click(Sender: TObject);
Var
 Str: String;
 Str2: String;
 P: Pointer;
begin
 Str2:='ABCDEF';
 Str:='abcdef';
 Asm
   push esi;
   push edi;

   mov edi,[Str]; //abcde
   Mov esi,[Str2];  //ABCDE

   mov al,[esi]; //al now = 65
   Mov [esi],al;  //make this char 65 (yes i know, but even this errors :| )

   pop edi;
   pop esi;
 End;
   showMessage(Str);
end;


why does that ERROR?! i'm going to give up at this rate.
0
Comment
Question by:tobjectpascal
  • 12
  • 7
19 Comments
 
LVL 4

Author Comment

by:tobjectpascal
ID: 17929353
var
 s: String;
begin
 SetLength(s,6);
  asm
    mov Esi,S;
    mov cx,65;
    mov [esi],cx;
  end;
 showMessage(S);

Is the solution, for some reason it does not like 8 bit registers going in.... odd

0
 
LVL 4

Author Comment

by:tobjectpascal
ID: 17929377
Var
 Str: String;
 Str2: String;
 P: Pointer;
begin
 Str2:='ABCDEF';
 Str:='abcdef';
 SetLength(Str,6);  //This fixes the code!, why? i'm not sure.
 Asm
   push esi;
   push edi;

   mov edi,[Str]; //abcde
   Mov esi,[Str2];  //ABCDE

   mov al,[esi]; //al now = 65
   Mov [edi],al;  //make this char 65 (yes i know, but even this errors :| )

   pop edi;
   pop esi;
 End;
   showMessage(Str);
0
 
LVL 4

Author Comment

by:tobjectpascal
ID: 17929400
// FillChar(Str[1],6,ord('?'));
// SetLength(Str,6);
// Str:=Str+'?';

Any of these Get the code working, my logical assumption is that the Compiler disregards Str because it's not used in my code... but if that were true it does not explain why you can extract from the string's array but not put it back.
0
 
LVL 4

Author Comment

by:tobjectpascal
ID: 17929645
asm
  Lea eax,Str;
  Mov edx,6;
  Call System.@LStrSetLength;
End;

sorts it though.
0
 
LVL 26

Accepted Solution

by:
Russell Libby earned 30 total points
ID: 17930161

The problem is that you are using strings in the asm code without performing the proper setup first. Not really recommended in the first place, but if you are going to do this, then you should be calling UniqueString on the string to be modified.  (Better practice is to use raw PChar data types in the asm code).

Russell

---
e.g.

procedure TForm1.Button2Click(Sender: TObject);
var  Str:     String;
     Str2:    String;
begin

  Str2:='ABCDEF';
  Str:='abcdef';
  asm
     push  eax
     push  esi;
     push  edi;
     lea   eax, [Str]        // Load str address
     call  UniqueString        // Make unique
     mov   esi, Str2;     // ABCDE
     mov   edi, [Str];    // abcde
     mov   al, [esi];     // Get "A"
     mov   [edi], al;     // Set abcdef to Abcdef
     pop   edi;
     pop   esi;
     pop   eax
  end;
  ShowMessage(Str);

end;
0
 
LVL 4

Author Comment

by:tobjectpascal
ID: 17935135

     lea   eax, [Str]       // Load str address
     call  UniqueString       // Make unique

So i'm guessing that SetLength does the same as UniqueString ?
0
 
LVL 4

Author Comment

by:tobjectpascal
ID: 17935138
anyway, thanks rlibby for all your help, As you probably can tell i'm trying to Learn BASM, problem i'm having is when to Push and when to move from Right to Left and when to Push to EAX EDX and ECX in that order...

But i think i'm slowly getting there :)

Thanks again.
0
 
LVL 26

Expert Comment

by:Russell Libby
ID: 17935180
Both the SetLength and UniqueString calls end up in the same place, which is _NewAnsiString, which handles the problem that the Delphi docs mention:

>> Only in cases where an application casts a string to a PChar and then modifies the contents of the string must UniqueString be used.

which is in effect what you are doing with the asm code.

Anyways, best of luck on your BASM work... its not always easy, but its usually quite rewarding.

Russell

0
 
LVL 4

Author Comment

by:tobjectpascal
ID: 17935800
Well i know i'm not offering any points, but this is really confusing me?

lea   eax, [Str]

not the same as

mov eax,offset [str]
 or
mov eax,str

I understand that's there's segments and indexes, Seg:howfarinto the segment

But Windows does not seem the same as when i touched on DOS assembly...

Load Effective Address
mov eax,Adre;

it's not a problem, as i can jsut use Lea but how on earth do you know what needs Lea... ugh

I can option up another question just for finding out the difference lol... but thanks for the help.
0
What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

 
LVL 26

Expert Comment

by:Russell Libby
ID: 17936036

LEA (load effective address) loads a 32 bit address with the *address* of the operand, vs. a MOV, which will set the 32 bit address with the *value* of the operand. Think of it like this:

Pointer(@Str) // This is like LEA
Pointer(Str)    // This is like MOV

The difference usually comes down to passing a param by value or by reference. Take for example the functions:

- LStrSetLength
- UniqueString

They are both defined as taking a "var String" parameter (by reference), thus the LEA would be use to setup the EAX register for the call to either of these. If you were calling a function that took a pchar / string constant, then the MOV would be used instead.

Russell
0
 
LVL 4

Author Comment

by:tobjectpascal
ID: 17936089
ahhh thank you very much :)

You are one of the few true experts in this forum :)
0
 
LVL 4

Author Comment

by:tobjectpascal
ID: 17936604
Rlibby...here's why i was confused (taken from my example above)

   mov al,[esi]; //al now = 65

Gives 65 (the data from the pointer, not the pointer address)

   mov al,esi; //al now = 65

Will not compile because it's passing the address to al, and the address is bigger than 8 bytes

   mov eax,[esi]; //passes the Data, not the Value
   mov eax,esi; //passes the Pointer to the data not the value

So if it passes the pointer...

why not
   Mov Eax,Str;  
instead of
  lea   eax, [Str]  

Technically they should both be the same result, but I've checked, it's not....

Which is why i got confused why not just Mov Eax, it's not passing the data but the pointer....

This is going to kill me... Rlibby, if you answer this i'll throw you my last remainig few points in a new thread just accept it when i created it :P




0
 
LVL 26

Expert Comment

by:Russell Libby
ID: 17938454
Yes, technically they are the same, therefore I can understand the confusion. The problem comes down to the inline compiler in Delphi. Take for instance the following asm code block within a procedure called Test:

procedure Test;
var X:     Integer;
begin

  asm
     mov   X, 100
     mov   eax, X
  end;
  ShowMessage(IntToStr(X));

end;

The variable X is pointer to the memory location at EBP-4 (this is KEY). If you perform the following:

   mov  eax, X

The inline assembler will turn your code into:

   mov eax, [ebp-4]

Which is exactly what we DONT want. (we don't want the value, we want the address). In fact, the inline compiler generates the same code for both usages:

   mov   eax [X]
   mov   eax, X

Its really not the compiler's fault either, as only LEA can be used to transfer a calculated addresss such as

  [ebp-4]

In order to do that with a MOV, you would have to do:

  mov eax, ebp-4

Which won't fly, thus the reason for LEA.....

------

Hopefully I didn't confuse you more. ;-)
Russell




wh

the EAX register will end up with the value 100. Keep in mind that variable X is nothing more than a pointer to 4 bytes of memory. It
0
 
LVL 26

Expert Comment

by:Russell Libby
ID: 17938463
>> wh
>>
>> the EAX register will end up with the value 100. Keep in mind that variable X is nothing more than a pointer to 4 bytes of memory. It


Please ignore my edits that I forget to cleanup before posting

Russell
0
 
LVL 4

Author Comment

by:tobjectpascal
ID: 17943438
ahhh interesting, thank you, i've got about 35 points remaming, you can have them :)
0
 
LVL 26

Expert Comment

by:Russell Libby
ID: 17943630
Dont' worry about it.

Russell
0
 
LVL 4

Author Comment

by:tobjectpascal
ID: 17955766
Serously.... I'm on to something here..

var
 s: String;
begin
 s:='hello world';
asm
  lea eax,s;
  call uniquestring;  //fine

  mov eax,s;
  call showmessage;  //fine
end;


var
 s: String;
begin
 s:='hello world';
asm
//  lea eax,s;
  mov eax,s;
  call uniquestring;  //boooooooom

 // mov eax,s;
  lea eax,s;
  call showmessage;  //booooooooom
end;

That's got to be Borland at fault.... not accepting the same method of getting the address twice, that can't be right i know.

The only rule i can see is, if it crashes, try the other way lol
0
 
LVL 26

Expert Comment

by:Russell Libby
ID: 17956252
Seriously, the rules are pretty straight forward.

1 - MOV cannot be used in Delphi's inline asm to transfer an address. LEA must be used to transfer an address.
2 - Functions that accept var Value will require a LEA to setup the register.
3 - Functions that accept (const) Value will require a MOV to setup the register.

The difference comes down to passing a param by value or by reference. UniqueString requires a var String (by reference). I already explained why MOV EAX, S isn't going to cut it for that. It generates a:

mov eax, [ebp-4]

which moves the VALUE not the address, so LEA *must* be used for var values. The ShowMessage routine on the other hand expects a string value, so MOV must be used to setup the eax register. If you use LEA, then its going to push the address and not the value, and the routine has no way of knowing the difference. And I'm sure you have probably read other articles on asm, which is why you are under the premise that:

MOV EAX, REG
and
LEA EAX, [REG]

are the same. But you have to understand that those docs are usually tailored to MASM / raw ASM development, and that it doesn't always apply to inline assemblers such as Delphi's. (Eg you can't use the EIP reg in the inline assembler, etc..). In this case MOV and LEA do NOT generate the same results.

Russell

0
 
LVL 4

Author Comment

by:tobjectpascal
ID: 17958272

Ok At Last... lol sorry to be a pain in the rear end russel, but i think i finally understand it, I managed to code a routine that works...  lol and yes thank you for your paitients, if the help file requires a return to a Pointer i use Lea, or i pass by Var, otherwise i use Mov and pass by value..

I think i'm starting to understand :D I do find it interesting that they Delphi has internal names for example LstrCat will cause an error and instead it requires LstrCat3 kinda odd but not a problem Mucho Gracias :)

procedure TForm1.Button1Click(Sender: TObject);
var
 Ret: Integer;
 ResString,Val,s,sub: String;
Const
 S2: String = 'Position: ';
begin
 s:='hello world';
 sub:='llo';
asm
  lea eax,s;
  call uniquestring;
  push eax;
 // call showmessage;
  mov eax,sub;
  pop edx;
  Call system.@lstrpos;
  mov ret,eax;
  lea edx,val;
  Call Inttostr;

  Lea Eax,ResString;
  Mov Ecx,Val;
  Mov Edx,S2;
  Call System.@LStrCat3;

  Mov Eax,ResString;
  call showmessage;
end;
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

The uses clause is one of those things that just tends to grow and grow. Most of the time this is in the main form, as it's from this form that all others are called. If you have a big application (including many forms), the uses clause in the in…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…
In this tutorial you'll learn about bandwidth monitoring with flows and packet sniffing with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're interested in additional methods for monitoring bandwidt…

706 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now