Author Topic: Making return values in procs  (Read 685 times)

Ascended

  • Member
  • ***
  • Posts: 331
Making return values in procs
« on: April 26, 2018, 09:56:09 AM »
Hi guys,

It's easy enough to make return values of DD's etc and 'mov' them in to your variable upon return.

But what if you want a return value of a struct?

Say you have a struct containing a dozen DD's for example, how to you handle that sort of thing on return?

Thanks in advance :)

Siekmanski

  • Member
  • *****
  • Posts: 1671
Re: Making return values in procs
« Reply #1 on: April 26, 2018, 10:40:14 AM »
I'm not sure if you meant this?

Code: [Select]
.const
MEDIATIMERS struct
    Timer1  dd ?
    Timer2  dd ?
    Timer3  dd ?
    Timer4  dd ?
MEDIATIMERS ends

.data?
align 4
Timers    MEDIATIMERS <?>

.code
    mov Timers.Timer1,0    ; write to struct member
    mov eax,Timers.Timer4  ; read from struct member
Creative coders use backward thinking techniques as a strategy.

jj2007

  • Member
  • *****
  • Posts: 8773
  • Assembler is fun ;-)
    • MasmBasic
Re: Making return values in procs
« Reply #2 on: April 26, 2018, 10:47:46 AM »
Perhaps it's not yet clear. You have two options:

- mov eax,Timers.Timer4: you return one value in eax (it could be another register - unusual but possible)

- eax returns just an error code; in this case, the proc got, as one argument, a pointer to the structure, and it filled the values into that structure. So, in a sense, you "return" a filled structure, plus an error code.

Ascended

  • Member
  • ***
  • Posts: 331
Re: Making return values in procs
« Reply #3 on: April 26, 2018, 11:07:44 AM »
I mean for example something like this (in C++)

Code: [Select]
Matrix c = MatrixMultiply(a, b);
So you feed in a and b, into a proc and it outputs the result in to 'newMat'.

How do you fill 'newMat' in ASM without using it as an input parameter.

At this stage I am doing a work around and using a 'c' input param as the result. But, how do you fill 'c' without using it as a parameter?


Siekmanski

  • Member
  • *****
  • Posts: 1671
Re: Making return values in procs
« Reply #4 on: April 26, 2018, 11:17:07 AM »
Code: [Select]
align 16
D3DMatrixMultiply proc pOut:DWORD,pM1:DWORD,pM2:DWORD
; Out = M1 * M2

mov     eax,pM2

movaps  xmm4,[eax]
movaps  xmm5,[eax+16]
movaps  xmm6,[eax+32]
movaps  xmm7,[eax+48]

mov     edx,pM1
mov     eax,pOut

i = 0
REPT 4
movaps  xmm0,[edx+i]
movaps  xmm1,xmm0
movaps  xmm2,xmm0
movaps  xmm3,xmm0
shufps  xmm0,xmm0,00000000b
shufps  xmm1,xmm1,01010101b
shufps  xmm2,xmm2,10101010b
shufps  xmm3,xmm3,11111111b
mulps   xmm0,xmm4
mulps   xmm1,xmm5
mulps   xmm2,xmm6
mulps   xmm3,xmm7
addps   xmm2,xmm0
addps   xmm3,xmm1
addps   xmm3,xmm2
movaps  [eax+i],xmm3
i = i + 16
ENDM   
ret
D3DMatrixMultiply endp
Creative coders use backward thinking techniques as a strategy.

Ascended

  • Member
  • ***
  • Posts: 331
Re: Making return values in procs
« Reply #5 on: April 26, 2018, 11:22:19 AM »
Isn't pOut a parameter though? Your Proc has 3 parameters.

You seem to be using the same 'workaround' as I am.

Siekmanski

  • Member
  • *****
  • Posts: 1671
Re: Making return values in procs
« Reply #6 on: April 26, 2018, 11:27:44 AM »
a == pM1
b == pM2
c == pOut

    invoke D3DMatrixMultiply,offset c,offset a,offset b

Matrices need to be 16 byte aligned.
Creative coders use backward thinking techniques as a strategy.

Ascended

  • Member
  • ***
  • Posts: 331
Re: Making return values in procs
« Reply #7 on: April 26, 2018, 11:34:06 AM »
I think you are missing the meaning of question.

I'll see if I can give a better example.


Take this example then (C++)

Code: [Select]
struct Thing
{
     float a,b,c,d,e,f,g,h;
}

Thing SomeFunc(Thing blah1, Thing blah2)
{
    // do something with thing blah1 & 2
    // doesn't really matter what

    return someNewThing;
}


Thing blahC
blahC = SomeFunc(blahA, blahB);

Siekmanski

  • Member
  • *****
  • Posts: 1671
Re: Making return values in procs
« Reply #8 on: April 26, 2018, 11:49:55 AM »
You have to create memory to write "blahC" to.
That's exactly what my routine does pOut is your blahC.

It reads 2 matrices, multiplies them and writes the new calculated matrix in pOut.
Creative coders use backward thinking techniques as a strategy.

Ascended

  • Member
  • ***
  • Posts: 331
Re: Making return values in procs
« Reply #9 on: April 26, 2018, 11:55:41 AM »
Ok, but just say you have the space created for blahC in the .data section? No way to write the result directly to that without passing as a parameter?

Siekmanski

  • Member
  • *****
  • Posts: 1671
Re: Making return values in procs
« Reply #10 on: April 26, 2018, 12:19:56 PM »
Yes, I have allocated memory for the empty matrix in the data section, the routine writes the result to that empty matrix memory.
Creative coders use backward thinking techniques as a strategy.

Ascended

  • Member
  • ***
  • Posts: 331
Re: Making return values in procs
« Reply #11 on: April 26, 2018, 12:21:21 PM »
Yes, but you still need to pass that as a param to the function. Can't just use it as a return value.

Siekmanski

  • Member
  • *****
  • Posts: 1671
Re: Making return values in procs
« Reply #12 on: April 26, 2018, 12:31:22 PM »
You must think in assembly now, your result is a return value of 64 bytes.
C++ maybe solves it for you, but now you're a real programmer and have to manage those things yourself.  :badgrin:
Creative coders use backward thinking techniques as a strategy.

Ascended

  • Member
  • ***
  • Posts: 331
Re: Making return values in procs
« Reply #13 on: April 26, 2018, 12:34:28 PM »
You must think in assembly now, your result is a return value of 64 bytes.
C++ maybe solves it for you, but now you're a real programmer and have to manage those things yourself.  :badgrin:

Yep, that's cool. Just wondering if there was a way to do this natively in ASM.  :t

I'll continue thinking 'out of the box'  :biggrin:

jj2007

  • Member
  • *****
  • Posts: 8773
  • Assembler is fun ;-)
    • MasmBasic
Re: Making return values in procs
« Reply #14 on: April 26, 2018, 12:53:55 PM »
You can, of course, write in your proc to a hardcoded matrix in the .data? section. But it's considered bad programming.

Your proc should work without that dirty trick. For example, you could HeapAlloc a new matrix inside the proc, and return the pointer in eax (or zero for failure); note, though, that HeapAlloc is align 8 (there is Alloc16 - maybe you find a CRT equivalent)