Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 251
  • Last Modified:

Built-in assembler problem

I'm writing a little graphical effect, and to speed things up a bit, I tried to replace some code by assembler. The problem is: how do you call another function using assembler. I already tried using "call @myFunction" but it says "@myFunction undeclared" or something. I only know the basics of assembler, so keep that in mind :)
0
herr_apfelschnitt
Asked:
herr_apfelschnitt
1 Solution
 
robert_marquardtCommented:
A simple trick:
Debug your application and have a look at the CPU window.
0
 
CynnaCommented:
herr_apfelschnitt,

> ... I already tried using "call @myFunction"...
Did you try "call myFunction"   ?:)

If your function has arguments, they are stored
in EAX, EDX and ECX in that order.
Function result is stored in EAX.

Simple demonstration:
-------------------------------


function bla(a,b: Integer): Integer;
begin
  Result:=a+b;
end;

function Assem: Integer;
asm
  mov EAX, 8;
  mov EDX, 3;
  call bla;
  mov Result, EAX;
end;

//---------------------------------------

procedure TForm1.Button11Click(Sender: TObject);
begin
  Label1.Caption:=IntToStr(Assem);
end;


0
 
herr_apfelschnittAuthor Commented:
wow! This is the first time something is easier than I thought it would be :)

You wouldn't mind me asking an additional question (or two) would you :) (since 200 pts is quite a lot, and I haven't got too many of them left)
(if you don't know the answer to these, don't worry, you get the points anyway)

1. How do you access the coprocessor's stack (ST(x))?
2. If the function has more than three arguments, are the remaining arguments simply put on the stack?

Thanks


0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
herr_apfelschnittAuthor Commented:
And to Robert:

I 've never seen a CPU window in Delphi. Could this be because i'm still running Delphi 3?
0
 
bugrogerCommented:
Hi,

how to Enable the CPU window in delphi 3?
-----------------------------------------
Simply go in the registry at:
HKCU\Software\Borland\Delphii\3.0\Debugging
then create a string key named "EnableCPU" and set the value to "1".
It's all.

it's from
http://www.delphipages.com/tips/thread.cfm?ID=10

0
 
CynnaCommented:
herr_apfelschnitt,

> 1. How do you access the coprocessor's stack (ST(x))?


Example (uses st(0) for floating point operations)
----------------------------------------------------------------

function FloatSubtract(a,b: Double): Double;
asm
 // Load first argument(memory) on top of stack, in st(0):
    fld a;
 // Subtract b(memory) from st(0) and place the result back in st(0):
    fsub b;
 // Pop st(0) to Result(memory)
    fstp Result;
end;

procedure TForm1.Button11Click(Sender: TObject);
begin
  Label1.Caption:=FloatToStr(FloatSubtract(4.5, 2.2));
end;


You can find further info in "Art Of Assembly Language":

* http://webster.cs.ucr.edu/Page_AoAWin/0_AoAHLA.html

The best thing would be to download the whole book.
Then go to  Chapter 11, "Real Arithmetic" (page 595).
Read up, you'll find quite detailed info on what you
seem to be interested in...





> 2. If the function has more than three arguments, are the remaining arguments simply put on the stack?

Generally, yes.
Here is what Delphi Help ("Program control" -> "Parameter passing") has to say about this:

"Under the register convention, up to three parameters are passed in CPU registers, and the rest (if any) are passed on the stack. The parameters are passed in order of declaration (as with the pascal convention), and the first three parameters that qualify are passed in the EAX, EDX, and ECX registers, in that order. Real and method-pointer types do not qualify as register parameters, but all other parameters do. If more than three parameters qualify as register parameters, the first three are passed in EAX, EDX, and ECX, and the remaining parameters are pushed onto the stack in order of declaration. For example, given the declaration

procedure Test(A: Integer; var B: Char; C: Double; const D: string; E: Pointer);

a call to Test passes A in EAX as a 32-bit integer, B in EDX as a pointer to a Char, and D in ECX as a pointer to a long-string memory block; C and E are pushed onto the stack as two double-words and a 32-bit pointer, in that order."




But, you can directly access your arguments and not worry
about this:

Example:
----------------

function MassSum(a,b,c,d,e: Integer): Integer;
asm
  mov EAX, a;
  mov EDX, b;
  add EAX, EDX;
  mov EDX, c;
  add EAX, EDX;
  mov EDX, d;
  add EAX, EDX;
  mov EDX, e;
  add EAX, EDX;
  mov Result, EAX;
end;

procedure TForm1.Button11Click(Sender: TObject);
begin
  Label1.Caption:=IntToStr(MassSum(1,2,3,4,5));
end;

0

Featured Post

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now