Passing const strings to asm routine

In a class called TShareBlock, with members

ptr : Pointer;
hMem : PChar;
FSize : Integer;

There is a method Add which increments the ptr member by n bytes after doing some range checking. (the add method source is shown below)

Should the range check fail, Add preempts the _RaiseException routine, which merely raises a new exception with the error string passed into it.
_RaiseException is not a member function. It is declared in the same scope as the class itself.

My problem is that the assembler add routine needs to call _RaiseException with a constant string. How do I pass the constant string into _RaiseException.

SMemError is declared in the implementation section of the unit as a const

const
        SMemError = 'Memory Overrun in Share Block.'

When SMemerror is declared as a var (as opposed to const) in the unit,
_RaiseException collects the variable (in EAX) correctly, and shows the
exception string.
when SMemError is declared as a const there is an access violation in the
_RaiseException code.

How are const strings passed into procedures using the inline assembler in
Delphi 3.00?

Note that the declaration of the _RaiseException routine can be _RaiseException ( const s : String) or.
_RaiseException ( s : String ) the const here makes no difference to the success of the asm call.

Awaiting your kind resposes.
Regards
Craig


(* Code snippits *)
Procedure TShareBlock.Add( n : Integer );
        begin
                asm
                MOV  ECX, [EAX].&ptr
                ADD  ECX, EDX
                MOV  EDX, [EAX].hMem
                ADD  EDX, [EAX].FSize
                CMP  EDX, ECX
                JAE  @@Z
                MOV  EAX, SMemError
                CALL _RaiseException       // Raise Exception
                JZ   @@E
            @@Z:
                MOV  [EAX].&ptr, ECX
            @@E:
        end;
end;

Procedure _RaiseException(const s : String );
// Collects s in EAX, as it is not a member procedure, otherwise it would
// be in EDX.
        begin
                raise Exception.Create(s);
        end;
LVL 1
cmainAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

cmainAuthor Commented:
Edited text of question
0
andrewjbCommented:
Untyped constants are effectively treated as textual replacement by the compiler. That is why it doesn't work.

If you define the SMemError to be a constant string i.e :
const
  SMemError : string = 'memory ...';

Then you can use
  Mov EAX , SMemError.

Otherwise the compiler doesn't really know what SMemError is, so the assignment to EAX gives you a pointer that is only valid at compile time, or something ...




0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
cmainAuthor Commented:
Great Answer,
I am suitably impressed.

One thing I would like to add though.
Your textual replacement justification for your answer raises an interesting point.
The delphi help file documentation shows an example of a local constant (admitedly an integer constant) that is referenced by it's name in the assembler. In this case it cannot be mere textual replacement?

I have tested my code with your example, and it works perfectly.
Your answer was excellent. Thanks.

0
andrewjbCommented:
Hmmm. I noticed that, too. It isn't quite textual replacement.

If you've an untyped string constant, then you seem to get a spurious pointer when you assign it in assembler. I'd guess that the string is stored somewhere for the compilation process only, so it doesn't work when you run the program.

Who knows how Borland think ?!
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Delphi

From novice to tech pro — start learning today.