Link to home
Start Free TrialLog in
Avatar of acerola
acerola

asked on

asm functions and pointers

i'm learning to make asm functions inside pascal 7 and
i've figured out that the return value for the function
is the value in AX. but that is at most a word. how do
i send the function a pointer as parameter and read/modify
its value?
ASKER CERTIFIED SOLUTION
Avatar of gete
gete

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of snirad
snirad

Hi acerola, you said that you have learned how to return values in the AX but at most you can only return a word.  This isn't fully true.  For larger DWord size object such as pointers and LongInts you can use the DX:AX pair.  The following program should give you a good example of how to do this along with a few other tricks you may find helpful.


{  This Program is a simple demonstration of how to use Pointers from within}
{  assembler functions in Pascal.}
PROGRAM TestPtr;

{  Even though NIL in Borland Pascal should always be the value of 0:0 it    }
{  is good to make your code as compatibly with other versions as possible.  }
{  Defining constants for the segment and offset values of NIL and assigning }
{  them formulas will both make it easier to change you code if you need to  }
{  and increase the chances of not needing to change it at all.              }
CONST
  kNilOfs = LongInt(NIL) AND $0000FFFF;
  kNilSeg = LongInt(NIL) SHR 16;

{  This function returns the value of P and then clears P by assigning it NIL}
FUNCTION ClearPointer(VAR P: Pointer): Pointer; ASSEMBLER;
ASM
        LES     DI,P           {Get the Pointers address}
        MOV     AX,ES:[DI]     {Load it’s offset}
        MOV     DX,ES:[DI+2]   {Load it’s segment}
  {DX:AX now has P loaded and is ready to be returned}
        MOV     CX,kNilOfs     {Load CX with the offset of Nil}
        MOV     ES:[DI],CX     {Store the offset}
        MOV     CX,kNilSeg     {Load CX with the segment of Nil}
        MOV     ES:[DI+2],CX   {Store the segment}
  {We're done!}
END;

VAR
  OriginalPtr, ReturnedPtr: Pointer;

BEGIN
{This point on is an example of how to use ClearPointer}
  OriginalPtr:= Ptr(1234, 5678);
  ReturnedPtr := ClearPointer(OriginalPtr);
  IF OriginalPtr<>NIL THEN
    WriteLn('ERROR: ClearPointer failed to place the value of NIL in OriginalPtr!')
  ELSE
    WriteLn('SUCCESS: ClearPointer successfully place the value of NIL in OriginalPtr!');
  WriteLn('The value of ReturnedPtr is ',Seg(ReturnedPtr^),':',Ofs(ReturnedPtr^),'.');
END.