Board index » delphi » Calling procedures in inline assembler : HELP NEEDED!

Calling procedures in inline assembler : HELP NEEDED!

Hello everybody!

    I'm programming using the inline assembler of Turbo Pascal 7.0.
I am writing a SVGA sprite writing routine, and I need to switch
banks at some point. I have a procedure called SetBank(Bank:word)
that works fine, but I can't call it in assembler because I don't
know how to give the parameters. So I tried putting my parameter in
a global variable, and calling an other bank switching routine with
no parameters but that uses that variable. It doesn't seem to be
able to switch the bank properly.
    Is there anything i'm missing? Should there be special lines before
and after the CALL? Note that I'm accessing a pointer that contains
the data of the sprite. Does that change something?
The code looks a little like this :
Asm
 Push DS
lds si,[sprite] {sprite is the pointer to an array}
 mov ax,$a000
 mov es,ax
{Etc... I use lodsb to load from the array and [ES:DI] to put in
video memory. Then I need to switch banks to 1, for example :}
 mov [Bank2Set],1
 Call SetTheBank {SetThebank uses Bank2Set as the number of the bank}
{Continue drawing ....}
 Pop ds
end;

Can anyone help me? Please E-Mail me at z...@music.mus.polymtl.ca.

 

Re:Calling procedures in inline assembler : HELP NEEDED!


Quote
In article <23MAR96.11871364.0...@music.mus.polymtl.ca> Zikovsky wrote:
>Date:       23 MAR 96 10:59:31 EST
>From:       Zikovsky <Z...@music.mus.polymtl.ca>
>Sender:     use...@music.mus.polymtl.ca
>Newsgroups: comp.lang.pascal.borland,comp.lang.pascal.misc
>Subject:    Calling procedures in inline assembler : HELP NEEDED!

>Hello everybody!

>    I'm programming using the inline assembler of Turbo Pascal 7.0.
>I am writing a SVGA sprite writing routine, and I need to switch
>banks at some point. I have a procedure called SetBank(Bank:word)
>that works fine, but I can't call it in assembler because I don't
>know how to give the parameters. So I tried putting my parameter in
>a global variable, and calling an other bank switching routine with
>no parameters but that uses that variable. It doesn't seem to be
>able to switch the bank properly.
>    Is there anything i'm missing? Should there be special lines before
>and after the CALL? Note that I'm accessing a pointer that contains
>the data of the sprite. Does that change something?
>The code looks a little like this :
>Asm
> Push DS
>lds si,[sprite] {sprite is the pointer to an array}
> mov ax,$a000
> mov es,ax
>{Etc... I use lodsb to load from the array and [ES:DI] to put in
>video memory. Then I need to switch banks to 1, for example :}
> mov [Bank2Set],1
> Call SetTheBank {SetThebank uses Bank2Set as the number of the bank}
>{Continue drawing ....}
> Pop ds
>end;

>Can anyone help me? Please E-Mail me at z...@music.mus.polymtl.ca.

I don't know what "SetTheBank" looks like, but I will assume it is a Pascal
procedure.  For starters, you probably need to save your working registers
and restore the environment before making the call and then restore your
parameters and working environment when it returns. The second thing is to
push SetTheBank's parameters onto the stack.

  push DS; push SI              { save sprite }
  push ES                       { save video segment }
  mov  AX,SEG @DATA; mov DS,AX  { Restore DS/DATA segment }
  push [Bank2Set]               { or use mov AX,1; push AX }
  call SetTheBank
  pop  ES                       { Restore video segment }
  pop  SI; pop DS               { Restore sprite }

Note that the bank parameter was not removed from the stack. In Pascal, it is
the responsibility of the called routine to remove it's parameters. In this
case, SetTheBank would "pop" the word parameter before it returned.

If you know where in relation to BP the DS register was pushed, you could use
something like  mov DS,[BP-PushedDS] to retrieve it.  This of course requires
that the routine we are in to have formal parameters or local variables that
would cause the compiler to generate the necessary code to implement a stack
frame.  Another, somewhat safer method is to declare a local variable and
store and restore DS from it.

VAR DSreg: Word;
Begin
    mov [DSreg],DS

    --- do your thing ---

    mov DS,[DSreg]

    --- some more from above ---

    mov DS,[DSreg]
End;

Doing anything less than saving your work register and restoring DS/BP before
calling another routine should be done only because you have an intimate
knowledge of the inner workings of the called routine.  In which case you
should also insure the called routine has comments describing which registers
it _must_ preserve, and things that it doesn't care about or are considered
normal or standard practice.  If you have any type of error checking enabled,
yuu'd best think twice before calling another routine without having DS
properly set.

                        ...red

Re:Calling procedures in inline assembler : HELP NEEDED!


Quote
In article <23MAR96.11871364.0...@music.mus.polymtl.ca> Zikovsky wrote:
>Hello everybody!

>    I'm programming using the inline assembler of Turbo Pascal 7.0.
>I am writing a SVGA sprite writing routine, and I need to switch
>banks at some point. I have a procedure called SetBank(Bank:word)
>that works fine, but I can't call it in assembler because I don't
>know how to give the parameters. So I tried putting my parameter in
>a global variable, and calling an other bank switching routine with
>no parameters but that uses that variable. It doesn't seem to be
>able to switch the bank properly.
>    Is there anything i'm missing? Should there be special lines
> before
>and after the CALL? Note that I'm accessing a pointer that contains
>the data of the sprite. Does that change something?
>The code looks a little like this :
>Asm
> Push DS
>lds si,[sprite] {sprite is the pointer to an array}
> mov ax,$a000
> mov es,ax
>{Etc... I use lodsb to load from the array and [ES:DI] to put in
>video memory. Then I need to switch banks to 1, for example :}
> mov [Bank2Set],1
> Call SetTheBank {SetThebank uses Bank2Set as the number of the bank}
>{Continue drawing ....}
> Pop ds
>end;

>Can anyone help me? Please E-Mail me at z...@music.mus.polymtl.ca.

I don't know what "SetTheBank" looks like, but I will assume it is a
Pascal procedure.  For starters, you probably need to save your working
registers and restore the environment before making the call and then
restore your parameters and working environment when it returns. The
second thing is to push SetTheBank's parameters onto the stack.

  push DS; push SI              { save sprite }
  push ES                       { save video segment }
  mov  AX,SEG @DATA; mov DS,AX  { Restore DS/DATA segment }
  push [Bank2Set]               { or use mov AX,1; push AX }
  call SetTheBank
  pop  ES                       { Restore video segment }
  pop  SI; pop DS               { Restore sprite }

Note that the bank parameter was not removed from the stack. In Pascal,
it is the responsibility of the called routine to remove it's
parameters. In this case, SetTheBank would "pop" the word parameter
before it returned.

If you know where in relation to BP the DS register was pushed, you
could use something like  mov DS,[BP-PushedDS] to retrieve it.  This of
course requires that the routine we are in to have formal parameters or
local variables that would cause the compiler to generate the necessary
code to implement a stack frame.  Another, somewhat safer method is to
declare a local variable and store and restore DS from it.

VAR DSreg: Word;
Begin
    mov [DSreg],DS

    --- do your thing ---

    mov DS,[DSreg]

    --- some more from above ---

    mov DS,[DSreg]
End;

Doing anything less than saving your work register and restoring DS/BP
before calling another routine should be done only because you have an
intimate knowledge of the inner workings of the called routine.  In
which case you should also insure the called routine has comments
describing which registers it _must_ preserve, and things that it
doesn't care about or are considered normal or standard practice.  If
you have any type of error checking enabled, yuu'd best think twice
before calling another routine without having DS properly set.

   ...red

Other Threads