Author Topic: Making return values in procs  (Read 563 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: 1597
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 their strategy.

jj2007

  • Member
  • *****
  • Posts: 8599
  • 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: 1597
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 their 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: 1597
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 their 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: 1597
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 their 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: 1597
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 their 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: 1597
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 their 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: 8599
  • 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)