News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

How can I call a function that takes a real8 argument?

Started by hamper, November 08, 2013, 12:36:36 AM

Previous topic - Next topic

hamper

The OpenGL function glFrustum takes six real8 arguments. Unfortunately, there isn't a "vector" version of this function as far as I can see, so I can't just set up an array of real8 values and pass a pointer.

When I try this, for example...

.data
myvar1 real8 6.7
.code
start:
push myvar1

...I get an error A2070 Invalid instruction operands

So I guess that the assembler won't let me push a quadword value onto the stack? (I'm using stdcall and .686 by the way).

If that's the case, then how can I call any function that takes a real8 argument? I know it must be possible, somehow, because C can do it ;) So how can it be done in assembly language?

Any help would be greatly appreciated.

hutch--

If it won't accept an address, a real8 is 64 bit, use 2 32 bit PUSH mnemonics to load the real8 value onto the stack.

hamper

Yes, but how can I split a real8 value and push both parts onto the stack in such a way that the function reads a single real8 value from the stack?

qWord

push first the high- than the low DWORD:
push DWORD ptr myReal8[4]
push DWORD ptr myReal8


When using the correct prototype, the INVOKE directive also does the job:
glFrustum proto stdcall left:REAL8,right:REAL8,bottom:REAL8,top:REAL8,zNear:REAL8,zFar:REAL8
...
invoke glFrustum,myReal8,...
MREAL macros - when you need floating point arithmetic while assembling!

hamper

Yes, that works fine.
Many thanks. I'm actually a bit ashamed I didn't already think of that!  :eusa_boohoo: After all, I spent enough time (at the time) on the various addressing modes. I should have realised. Guess it's one of those days. Oh well. But thanks for clarifying it.

TouEnMasm

Just use the correct declaration for the function
Quote
glFrustum PROTO :QWORD ,:QWORD ,:QWORD ,:QWORD ,:QWORD ,:QWORD
or
glFrustum PROTO :REAL8 ,:REAL8 ,:REAL8 ,:REAL8 ,:REAL8 ,:REAL8

Masm also accept structures in a declare Prototype
Fa is a musical note to play with CL

jj2007

A quick search in the include folder shows that REAL8 args are very rare: There is only one function call, VariantTimeToSystemTime, in one dll, OleAut32, which takes a REAL8 arg.

TWell

---------- WIN\OLEAUTO.H
STDAPI VarDecCmpR8(LPDECIMAL,double);
STDAPI VarCyCmpR8(CY,double);
STDAPI VarR8Pow(double,double,double*);
STDAPI VarR4CmpR8(float,double);
STDAPI VarR8Round(double,int,double*);

---------- WIN\OLEAUTO.H
WINOLEAUTAPI_(INT) DosDateTimeToVariantTime(USHORT,USHORT,DOUBLE*);
WINOLEAUTAPI_(INT) VariantTimeToDosDateTime(DOUBLE,USHORT*,USHORT*);
WINOLEAUTAPI_(INT) SystemTimeToVariantTime(LPSYSTEMTIME,DOUBLE*);
WINOLEAUTAPI_(INT) VariantTimeToSystemTime(DOUBLE,LPSYSTEMTIME);
WINOLEAUTAPI VarUI1FromR8(DOUBLE,BYTE*);
WINOLEAUTAPI VarI2FromR8(DOUBLE,SHORT*);
WINOLEAUTAPI VarI4FromR8(DOUBLE,LONG*);
WINOLEAUTAPI VarR4FromR8(DOUBLE,FLOAT*);
WINOLEAUTAPI VarR8FromUI1(BYTE,DOUBLE*);
WINOLEAUTAPI VarR8FromI2(SHORT,DOUBLE*);
WINOLEAUTAPI VarR8FromI4(LONG,DOUBLE*);
WINOLEAUTAPI VarR8FromR4(FLOAT,DOUBLE*);
WINOLEAUTAPI VarR8FromCy(CY,DOUBLE*);
WINOLEAUTAPI VarR8FromDate(DATE,DOUBLE*);
WINOLEAUTAPI VarR8FromStr(OLECHAR*,LCID,ULONG,DOUBLE*);
WINOLEAUTAPI VarR8FromDisp(IDispatch*,LCID,DOUBLE*);
WINOLEAUTAPI VarR8FromBool(VARIANT_BOOL,DOUBLE*);
WINOLEAUTAPI VarR8FromI1(CHAR,DOUBLE*);
WINOLEAUTAPI VarR8FromUI2(USHORT,DOUBLE*);
WINOLEAUTAPI VarR8FromUI4(ULONG,DOUBLE*);
WINOLEAUTAPI VarR8FromDec(DECIMAL*,DOUBLE*);
WINOLEAUTAPI VarDateFromR8(DOUBLE,DATE*);
WINOLEAUTAPI VarCyFromR8(DOUBLE,CY*);
WINOLEAUTAPI VarBstrFromR8(DOUBLE,LCID,ULONG,BSTR*);
WINOLEAUTAPI VarBoolFromR8(DOUBLE,VARIANT_BOOL*);
WINOLEAUTAPI VarI1FromR8(DOUBLE,CHAR*);
WINOLEAUTAPI VarUI2FromR8(DOUBLE,USHORT*);
WINOLEAUTAPI VarUI4FromR8(DOUBLE,ULONG*);
WINOLEAUTAPI VarDecFromR8(DOUBLE,DECIMAL*);

jj2007

Quote from: TWell on December 08, 2013, 10:24:04 AM
---------- WIN\OLEAUTO.H
STDAPI VarDecCmpR8(LPDECIMAL,double); = :DWORD,:DWORD,:DWORD
STDAPI VarCyCmpR8(CY,double); = :DWORD,:DWORD,:DWORD,:DWORD
STDAPI VarR8Pow(double,double,double*); = :DWORD,:DWORD,:DWORD,:DWORD,:DWORD
STDAPI VarR4CmpR8(float,double); = :DWORD,:DWORD,:DWORD
STDAPI VarR8Round(double,int,double*);

---------- WIN\OLEAUTO.H
WINOLEAUTAPI_(INT) DosDateTimeToVariantTime(USHORT,USHORT,DOUBLE*); = :DWORD,:DWORD,:DWORD
WINOLEAUTAPI_(INT) VariantTimeToDosDateTime(DOUBLE,USHORT*,USHORT*); = :DWORD,:DWORD,:DWORD,:DWORD
...

I guess it works, somehow... and it would break existing code if we "corrected" it now ;-)

dedndave

there are a few functions that pass structures (per MSDN)
but, Hutch has modified the prototype to accept DWORD's
a couple that come to mind are PtInRect and SetConsoleCursorPosition