flat assembler
Message board for the users of flat assembler.

Index > High Level Languages > Return values

Author
Thread Post new topic Reply to topic
kohlrak



Joined: 21 Jul 2006
Posts: 1421
Location: Uncle Sam's Pad
kohlrak 13 Dec 2006, 21:49
I don't know if this has been asked before or not, but i went through 2 pages of the search thing and found nothing on it. Can some one do me a favor and explain how programs in assembly handle return values from C/C++ DLLs?
Post 13 Dec 2006, 21:49
View user's profile Send private message Visit poster's website AIM Address Yahoo Messenger MSN Messenger Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid 13 Dec 2006, 22:18
in 32bit code, return values are simply stored in EAX. so it's just something like:
Code:
call c_func
cmp eax, 0
je error    
Post 13 Dec 2006, 22:18
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
kohlrak



Joined: 21 Jul 2006
Posts: 1421
Location: Uncle Sam's Pad
kohlrak 14 Dec 2006, 01:36
Is that for all return types such as char, pointer, and such? And what about doubles? Is a pointer passed to eax, or should i expect that to be placed on ebx before the return?
Post 14 Dec 2006, 01:36
View user's profile Send private message Visit poster's website AIM Address Yahoo Messenger MSN Messenger Reply with quote
f0dder



Joined: 19 Feb 2004
Posts: 3175
Location: Denmark
f0dder 14 Dec 2006, 01:53
For 32bit code, quantities larger than 32bit can be returned in various ways... like EDX:EAX for 64bit integers, and ST(0) for floating-point results. Will depend on compiler though... but EDX:EAX and ST(0) are good bets.
Post 14 Dec 2006, 01:53
View user's profile Send private message Visit poster's website Reply with quote
kohlrak



Joined: 21 Jul 2006
Posts: 1421
Location: Uncle Sam's Pad
kohlrak 14 Dec 2006, 01:58
So, essentually, as long as the data can fit in eax, i can expect it to be in eax (or al for a single char). I don't know much about microsoft's little pet, the HANDLE, but i'll assume that's a 32bit value that is sent to eax, because if it's only an id tag, it shoudn't be any bigger than that. lol

And thank you both.
Post 14 Dec 2006, 01:58
View user's profile Send private message Visit poster's website AIM Address Yahoo Messenger MSN Messenger Reply with quote
Plue



Joined: 15 Dec 2005
Posts: 151
Plue 14 Dec 2006, 16:28
kohlrak wrote:
So, essentually, as long as the data can fit in eax, i can expect it to be in eax (or al for a single char).
No, a 32-bit float will fit in eax, but is returned at the top of the FPU stack. A 64-bit float will fit in edx:eax but will also be returned at the top of the FPU stack.

HANDLEs are returned in eax, no problem there.
Edit: CHARs are also returned in eax, NOT al.

_________________
Roses are red
Violets are blue
Some poems rhyme
And some don't.
Post 14 Dec 2006, 16:28
View user's profile Send private message Reply with quote
kohlrak



Joined: 21 Jul 2006
Posts: 1421
Location: Uncle Sam's Pad
kohlrak 14 Dec 2006, 23:40
Well, it's safe to say that if it is returned to eax it'll be restricted to al, anyway, because it's only 1 byte.
Post 14 Dec 2006, 23:40
View user's profile Send private message Visit poster's website AIM Address Yahoo Messenger MSN Messenger Reply with quote
f0dder



Joined: 19 Feb 2004
Posts: 3175
Location: Denmark
f0dder 15 Dec 2006, 00:30
Plue wrote:

No, a 32-bit float will fit in eax, but is returned at the top of the FPU stack. A 64-bit float will fit in edx:eax but will also be returned at the top of the FPU stack.

Iirc Watcom returned floats in EAX... at least I'm pretty sure I've seen some compiler do that.
Post 15 Dec 2006, 00:30
View user's profile Send private message Visit poster's website Reply with quote
kohlrak



Joined: 21 Jul 2006
Posts: 1421
Location: Uncle Sam's Pad
kohlrak 15 Dec 2006, 00:47
Well, C++'s method for returning values has to be standard, otherwise DLLs wouldn't work well.
Post 15 Dec 2006, 00:47
View user's profile Send private message Visit poster's website AIM Address Yahoo Messenger MSN Messenger Reply with quote
madmatt



Joined: 07 Oct 2003
Posts: 1045
Location: Michigan, USA
madmatt 15 Dec 2006, 09:59
You could pass an address to a Double float and store it that way:
mov eax, [addresstoDouble]
fstp qword [eax]

You could pass a struct the same way, just use pointers.
mov eax, [pointertobitmapstruct]
mov ecx, [eax + BITMAPFILEHEADER.bfSize]
Post 15 Dec 2006, 09:59
View user's profile Send private message Reply with quote
Plue



Joined: 15 Dec 2005
Posts: 151
Plue 21 Dec 2006, 11:54
kohlrak wrote:
Well, it's safe to say that if it is returned to eax it'll be restricted to al, anyway, because it's only 1 byte.
But you can do this:

Code:
call ProcedureReturnsAByte
mov dword [v_Long], eax    


and v_Long will have the correct value. So a procedure that returns a byte must clear eax completely first and extend the sign bit of the byte to a long if it is declared as signed.

_________________
Roses are red
Violets are blue
Some poems rhyme
And some don't.
Post 21 Dec 2006, 11:54
View user's profile Send private message Reply with quote
kohlrak



Joined: 21 Jul 2006
Posts: 1421
Location: Uncle Sam's Pad
kohlrak 22 Dec 2006, 02:37
But if it did that, well.. Let's take the following code for example:

Code:
proc charfunc
mov eax, 244
add eax, eax ;... accidental add instead of xor
ret
endp    


Then you have the same idiot under visual studio...

Code:
#pragma comment(lib, "charfuncdll.lib")
//insert directive to import function as a char here, since i forget it.
void main(){ //Yes, i'm making him a complete idiot.
char a=charfuc;
return; } //Yes, does absolutely nothing with it...    


I guess a would have a (no pun intended) value of E8 or 0C? Nice warning, Plue.
Post 22 Dec 2006, 02:37
View user's profile Send private message Visit poster's website AIM Address Yahoo Messenger MSN Messenger Reply with quote
f0dder



Joined: 19 Feb 2004
Posts: 3175
Location: Denmark
f0dder 22 Dec 2006, 03:11
It would of course be E8.

Or well, with the code above you'd get a compiler error Wink

What you want is the following:
Code:
extern char charfunc(void);
int main()
{
        volatile char a = charfunc();
}
    

Which produces the following assembly ("cl /c /Ox /FAs blabla.c" for MSVC 14.00.50727.42, aka .net2005):
Code:
_main   PROC
        push    ecx
        call    _charfunc
        mov             BYTE PTR _a$[esp+4], al
        xor             eax, eax
        pop             ecx
        ret             0
_main   ENDP
    


Now why the hell it does push/pop ecx I don't know, but it might be the "volatile" that messes something up. Without volatile, no code is produced, because of optimizations.
Post 22 Dec 2006, 03:11
View user's profile Send private message Visit poster's website Reply with quote
kohlrak



Joined: 21 Jul 2006
Posts: 1421
Location: Uncle Sam's Pad
kohlrak 22 Dec 2006, 03:13
woops. lol I don't do that one often, but i did it recently in my C++ class... lol Then i wondered why i got these really weird numbers (pointers XD).
Post 22 Dec 2006, 03:13
View user's profile Send private message Visit poster's website AIM Address Yahoo Messenger MSN Messenger Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.