1. RE: QWORD (int64) question

Elliott Sales de Andrade wrote:
> I think I asked this before, but I would like to know how to get return 
> values that are QWORD's. Someone said that QWORD's are pointers, but 
> they 
> are not. When passing QWORD's they use two INT's in VB, so it is 
> definitely 
> not 32 bits. I am guessing that I would have to use ASM to do this. From 
> my 
> limited knowledge of 16-bit assembler, I happen to know that return 
> values 
> that were 32 bits (which was not as usual, of course) were in DX:AX. So, 
> I'm 
> guessing that in 32-bit assembly a 64-bit value would be returned in 
> EDX:EAX. Any help would be appreciated.
> 
> 
> Euphoria Instant Messenger
> Have YOU Joined?
> http://groups.yahoo.com/group/euim/
> 
> 

hi Elliot
while on the actual Euforum i used the search function on the title bar 
: '64 bit' and got responses which would answer your question.

lots of knowledgeable people on the forum.

rudy


lotterywars

new topic     » topic index » view message » categorize

2. RE: QWORD (int64) question

rudy toews wrote:
>
>hi Elliot
>while on the actual Euforum i used the search function on the title bar
>: '64 bit' and got responses which would answer your question.
>
>lots of knowledgeable people on the forum.
>
>rudy
>
>
>lotterywars

I tried searching on Topica and  at the RDS website. I don't believe I found 
an answer to my question. I did see something about 64-bit floating point 
values, but they are a different matter. Could you point me to a page that 
might help?

Euphoria Instant Messenger
Have YOU Joined?
http://groups.yahoo.com/group/euim/

new topic     » goto parent     » topic index » view message » categorize

3. RE: QWORD (int64) question

> From: Robert Craig [mailto:rds at RapidEuphoria.com]
> Elliott Sales de Andrade writes:
> > I think I asked this before, but I would like to know how 
> > to get return values that are QWORD's. Someone said 
> > that QWORD's are pointers, but they are not. When 
> > passing QWORD's they use two INT's in VB, so it is definitely 
> > not 32 bits. I am guessing that I would have to use ASM to do this.


> More likely, they use two 32-bit registers. You'd have to
> maybe disassemble some compiled C code to get the answer,
> and then use some machine code similar to Matt Lewis' DLL code.

I found this on http://gcc.gnu.org/ml/gcc-bugs/2000-02/msg00104.html

/*
 * All the functions listed here are C callable, and may also be called
 * from assembly using the C calling mechanism.  All INT64 functions
 * return their results in edx:eax, where edx is the upper longword.
 * Functions returning a long place the result in eax, and the contents
 * of edx are destroyed.  All other registers are preserved.
 */

Based on that, I think this code (untested) should work.  The only real
change from the standard code (in fptr.e) is that I added the mov edx to get
the second dword.  A similar fix could be added to the cdecl calls.  You can
use this to call a function that returns a qword, and it will return a
sequence of two 32-bit unsigned integers.  When I get a chance, I'll work
this into the main lib.

include machine.e
constant
q_fptr_asm = {
    #60,                    --    0: pusha
    #BB,#00,#00,#00,#00,    --    1: mov ebx, paramcount (2)
    #B9,#00,#00,#00,#00,    --    6: mov ecx, params (7)
                            --    B: start: 
    #8B,#01,                --    B: mov eax, [ecx]
    #50,                    --    D: push eax
    #83,#C1,#04,            --    E: add ecx, 4
    #4B,                    --   11: dec ebx
    #75,#F7,                --   12: jnz start
    #FF,#15,#00,#00,#00,#00,--   14: call dword ptr [comfunc] (22)
    #A5,#00,#00,#00,#00,    --   1A: mov [retpointer], eax (27)
    #A3,#00,#00,#00,#00,    --   1A: mov [retpointer], edx (31)
    #61,                    --   20: popa
    #C3},                   --   21: ret

q_fptr_paramcount = 2,
q_fptr_params = 7,
q_fptr_funcptr = 22+0,
q_fptr_retptr = 27+0,
q_retval = allocate(8),

q_fptr_asm_addr = allocate( length( q_fptr_asm ) + 20 * 5 )

constant
q_fptr_func = q_fptr_asm_addr + 33,
q_fptr_retval = q_fptr_asm_addr + 37,
q_fptr_param_ptr = q_fptr_asm_addr + 41

poke( fptr_asm_q_addr, fptr_q_asm )
poke4( q_fptr_asm_addr + q_fptr_funcptr, fptr_q_func )
poke4( q_fptr_asm_addr + q_fptr_params, q_fptr_param_ptr )
poke4( q_fptr_asm_addr + q_fptr_retptr, q_fptr_retval )
poke4( q_fptr_asm_addr + q_fptr_retptr + 5, q_fptr_retval + 4 )

global function call_fptr_qword( atom fptr, sequence params )
    sequence ret
    -- store the pointer to the function
    poke4( q_fptr_func, fptr )

    -- reverse the params for stdcall calling convention
    params = reverse(params)

    -- store the params
    poke4( q_fptr_param_ptr, params )

    -- tell the asm how many params to push
    poke4( q_fptr_asm_addr + q_fptr_paramcount, length(params) )
    -- run the asm
    call( q_fptr_asm_addr )

    -- get the value returned from the function
    ret = peek4u( {q_fptr_retval,2} )
    return ret
end function

Matt Lewis

new topic     » goto parent     » topic index » view message » categorize

4. RE: QWORD (int64) question

Thanks, it looks great. I'd like to know a few other things first though. 
First off, to get the first param for that function, I'm using 
GetProcAddress(). I'm using the value returned from open_dll(). I'm not sure 
if that is right, so I'd like to know. Second, I have a few functions that 
need to pass floats. So, how would I do this exactly? Just atom_to_float32() 
and then bytes_to_int() ?  TIA


Euphoria Instant Messenger
Have YOU Joined?
http://groups.yahoo.com/group/euim/


>From: Matthew Lewis <matthewwalkerlewis at YAHOO.COM>
> > From: Robert Craig [mailto:rds at RapidEuphoria.com]
> > Elliott Sales de Andrade writes:
> > > I think I asked this before, but I would like to know how
> > > to get return values that are QWORD's. Someone said
> > > that QWORD's are pointers, but they are not. When
> > > passing QWORD's they use two INT's in VB, so it is definitely
> > > not 32 bits. I am guessing that I would have to use ASM to do this.
>
>
> > More likely, they use two 32-bit registers. You'd have to
> > maybe disassemble some compiled C code to get the answer,
> > and then use some machine code similar to Matt Lewis' DLL code.
>
>I found this on http://gcc.gnu.org/ml/gcc-bugs/2000-02/msg00104.html
>
>/*
>  * All the functions listed here are C callable, and may also be called
>  * from assembly using the C calling mechanism.  All INT64 functions
>  * return their results in edx:eax, where edx is the upper longword.
>  * Functions returning a long place the result in eax, and the contents
>  * of edx are destroyed.  All other registers are preserved.
>  */
>
>Based on that, I think this code (untested) should work.  The only real
>change from the standard code (in fptr.e) is that I added the mov edx to 
>get
>the second dword.  A similar fix could be added to the cdecl calls.  You 
>can
>use this to call a function that returns a qword, and it will return a
>sequence of two 32-bit unsigned integers.  When I get a chance, I'll work
>this into the main lib.
>
>include machine.e
>constant
>q_fptr_asm = {
>     #60,                    --    0: pusha
>     #BB,#00,#00,#00,#00,    --    1: mov ebx, paramcount (2)
>     #B9,#00,#00,#00,#00,    --    6: mov ecx, params (7)
>                             --    B: start:
>     #8B,#01,                --    B: mov eax, [ecx]
>     #50,                    --    D: push eax
>     #83,#C1,#04,            --    E: add ecx, 4
>     #4B,                    --   11: dec ebx
>     #75,#F7,                --   12: jnz start
>     #FF,#15,#00,#00,#00,#00,--   14: call dword ptr [comfunc] (22)
>     #A5,#00,#00,#00,#00,    --   1A: mov [retpointer], eax (27)
>     #A3,#00,#00,#00,#00,    --   1A: mov [retpointer], edx (31)
>     #61,                    --   20: popa
>     #C3},                   --   21: ret
>
>q_fptr_paramcount = 2,
>q_fptr_params = 7,
>q_fptr_funcptr = 22+0,
>q_fptr_retptr = 27+0,
>q_retval = allocate(8),
>
>q_fptr_asm_addr = allocate( length( q_fptr_asm ) + 20 * 5 )
>
>constant
>q_fptr_func = q_fptr_asm_addr + 33,
>q_fptr_retval = q_fptr_asm_addr + 37,
>q_fptr_param_ptr = q_fptr_asm_addr + 41
>
>poke( fptr_asm_q_addr, fptr_q_asm )
>poke4( q_fptr_asm_addr + q_fptr_funcptr, fptr_q_func )
>poke4( q_fptr_asm_addr + q_fptr_params, q_fptr_param_ptr )
>poke4( q_fptr_asm_addr + q_fptr_retptr, q_fptr_retval )
>poke4( q_fptr_asm_addr + q_fptr_retptr + 5, q_fptr_retval + 4 )
>
>global function call_fptr_qword( atom fptr, sequence params )
>     sequence ret
>     -- store the pointer to the function
>     poke4( q_fptr_func, fptr )
>
>     -- reverse the params for stdcall calling convention
>     params = reverse(params)
>
>     -- store the params
>     poke4( q_fptr_param_ptr, params )
>
>     -- tell the asm how many params to push
>     poke4( q_fptr_asm_addr + q_fptr_paramcount, length(params) )
>     -- run the asm
>     call( q_fptr_asm_addr )
>
>     -- get the value returned from the function
>     ret = peek4u( {q_fptr_retval,2} )
>     return ret
>end function
>
>Matt Lewis

new topic     » goto parent     » topic index » view message » categorize

5. RE: QWORD (int64) question

> From: Elliott Sales de Andrade [mailto:quantum_analyst at hotmail.com]

> Thanks, it looks great. I'd like to know a few other things 
> first though. 
> First off, to get the first param for that function, I'm using 
> GetProcAddress(). I'm using the value returned from 
> open_dll(). I'm not sure 
> if that is right, so I'd like to know. 

Using GetProcAddress() is the correct method, although it's actually pretty
easy to get a pointer to a dll function without explicitly calling
GetProcAddress().  Just use define_c_variable() instead of define_c_func().


> Second, I have a few 
> functions that 
> need to pass floats. So, how would I do this exactly? Just 
> atom_to_float32() 
> and then bytes_to_int() ?  TIA

Yep.

Matt Lewis

new topic     » goto parent     » topic index » view message » categorize

6. RE: QWORD (int64) question

Alright, one last set of questions. These QWORD's will, most probably, be 
signed. So, I'll guess that instead of the line:
    ret = peek4u({q_fptr_retval, 2})
I'd need to put:
    ret = {peek4u(q_fptr_retval), peek4s(q_fptr_retval + 4)}
to get {unsigned low dword, signed high dword}.
And, last question,  how would i then put those two values together, if I 
needed to? I need to test for -1 values. Just multiplying the high dword and 
adding it to the low dword is good enough? Would that account for the 
negative?


>
>
> > From: Elliott Sales de Andrade [mailto:quantum_analyst at hotmail.com]
>
> > Thanks, it looks great. I'd like to know a few other things
> > first though.
> > First off, to get the first param for that function, I'm using
> > GetProcAddress(). I'm using the value returned from
> > open_dll(). I'm not sure
> > if that is right, so I'd like to know.
>
>Using GetProcAddress() is the correct method, although it's actually pretty
>easy to get a pointer to a dll function without explicitly calling
>GetProcAddress().  Just use define_c_variable() instead of define_c_func().
>
>
> > Second, I have a few
> > functions that
> > need to pass floats. So, how would I do this exactly? Just
> > atom_to_float32()
> > and then bytes_to_int() ?  TIA
>
>Yep.
>
>Matt Lewis

new topic     » goto parent     » topic index » view message » categorize

7. RE: QWORD (int64) question

> From: Elliott Sales de Andrade [mailto:quantum_analyst at hotmail.com]

Sorry for the late reply (been out of town).

> Alright, one last set of questions. These QWORD's will, most 
> probably, be 
> signed. So, I'll guess that instead of the line:
>     ret = peek4u({q_fptr_retval, 2})
> I'd need to put:
>     ret = {peek4u(q_fptr_retval), peek4s(q_fptr_retval + 4)}
> to get {unsigned low dword, signed high dword}.
> And, last question,  how would i then put those two values 
> together, if I 
> needed to? I need to test for -1 values. Just multiplying the 
> high dword and 
> adding it to the low dword is good enough? Would that account for the 
> negative?

Getting the hi word signed should work fine.  Then you could just try:

if hi_word < 0 then
  lo_word = -lo_word
end if

qword = lo_word + hi_word * #100000000

Of course, make sure that qword is an atom.  If the numbers get too big, you
will lose some precision (after 15 decimal digits).

Matt Lewis

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu