__stdcall alternative

B

Bartc

I'm mixing C and ASM, and for calling ASM from C, I just happened to use the
__stdcall convention (using C convention is not practical for other
reasons).

But, __stdcall seems to assume that machine registers are saved by the
called routine (as far as I can gather after a few hours messing with some
strange behaviours especially with optimised C code).

Is there any other call convention I can use likely to be commonly
available?

Or is there a way of specifying that an external function does not save
registers or is badly behaved?
 
I

Ian Collins

Bartc said:
I'm mixing C and ASM, and for calling ASM from C, I just happened to use the
__stdcall convention (using C convention is not practical for other
reasons).
What is __stdcall? It's not C, so it must be platform specific, try a
group for your platform, you'll get more help there.
 
J

jacob navia

Bartc said:
I'm mixing C and ASM, and for calling ASM from C, I just happened to use the
__stdcall convention (using C convention is not practical for other
reasons).

But, __stdcall seems to assume that machine registers are saved by the
called routine (as far as I can gather after a few hours messing with some
strange behaviours especially with optimised C code).

OBVIOUSLY you should save the registers ytour compiler thinks are permanent

Under windows (where stdcall is commonly used) you should save
(I am assuming 64 bit CPU)

rsi
rdi
rbx
r12-r15
rbp

And at the end you should issue a
ret $8

when you receive 8 bytes of arguments for instance.
Is there any other call convention I can use likely to be commonly
available?

you could just as well use the C calling convention. The registers to save
are THE SAME but you should just issue

ret
and the called procedure adjusts the stack.

Or is there a way of specifying that an external function does not save
registers or is badly behaved?

There is NO way to do that. YOU HAVE TO SAVE THOSE if not
you will just have a crash.
 
A

Antoninus Twink

There is NO way to do that. YOU HAVE TO SAVE THOSE if not
you will just have a crash.

It sounded to me like the external function isn't one he's written, and
he can't control its behavior. If that's the case, there's nothing for
it except to work out what calling convention the function expects, and
use that.
 
K

Keith Thompson

jacob navia said:
What's the point of showing your ignorance as it was a quality?

You do not know the subject matter?

Just stay silent! Is that too complicated?



Of course it is. It is a common extension.


no, it isn't

"_stdcall" isn't platform-specific? Seriously?
 
J

jacob navia

Eric said:
Oh, good! Then I'll start using it right away!

% cat foo.c
extern void __stdcall foo(void);
% cc foo.c
"foo.c", line 1: syntax error before or at: foo
"foo.c", line 1: warning: old-style declaration or incorrect type for: foo
cc: acomp failed for foo.c
%

Hmmm -- Something seems to be amiss. I'll try a
different machine and a different compiler:

foo.c:1: error: expected '=', ',', ';', 'asm' or '__attribute__' before
'foo'

What am I doing wrong? You've said __stdcall isn't
platform-specific, but I've tried two platforms and it doesn't
work on either of them!

If you use gcc you should
#ifndef STDCALL
#define STDCALL __attribute__((stdcall))
#endif
 
K

Keith Thompson

jacob navia said:
#ifndef STDCALL
#define STDCALL __attribute__((stdcall))
#endif

What does defining "STDCALL" have to do with "__stdcall"? They're two
different identifiers, you know.

I suppose your point is that gcc supports a feature that's similar to
"__stdcall", but uses the syntax "__attribute__((stdcall))". So two
different platforms support a similar feature using radically
different syntax. If I were sufficiently motivated, I'm sure I could
find another platform that either supports it with yet another
different syntax, or doesn't support it at all.

"__stdcall" is platform-specific.
 
I

Ian Collins

jacob said:
Just stay silent! Is that too complicated?
Fool, if you read the bit of my post you snipped - "try a group for your
platform, you'll get more help there." - you would see I was attempting
to help the OP.
Of course it is. It is a common extension.
Not on any platform I use, and that's quite a few.
no, it isn't
Eric's already shown you that is is.
 
J

jacob navia

Eric said:
... but you said __stdcall wasn't platform-specific, so
why do I have to write __attribute__((stdcall)) instead? And
what about the other platform I tried?

Go to the kindergarten then. There you will find all answers
 
J

jacob navia

Keith said:
What does defining "STDCALL" have to do with "__stdcall"? They're two
different identifiers, you know.

I suppose your point is that gcc supports a feature that's similar to
"__stdcall", but uses the syntax "__attribute__((stdcall))". So two
different platforms support a similar feature using radically
different syntax. If I were sufficiently motivated, I'm sure I could
find another platform that either supports it with yet another
different syntax, or doesn't support it at all.

"__stdcall" is platform-specific.

What piss me off of this regulars is that when they are proved
wrong they insist
 
J

jacob navia

Ian said:
Fool, if you read the bit of my post you snipped - "try a group for your
platform, you'll get more help there." - you would see I was attempting
to help the OP.

Not on any platform I use, and that's quite a few.

Eric's already shown you that is is.

And I showed Eric and you and Thompson that is supported
on gcc/MSVC/Lcc-win/Watcom/Borland and what have you

what piss me off of this regulars is that when proved wrong
they insist
 
I

Ian Collins

jacob said:
And I showed Eric and you and Thompson that is supported
on gcc/MSVC/Lcc-win/Watcom/Borland and what have you
Which are specific platforms, so?
what piss me off of this regulars is that when proved wrong
they insist
On what?
 
J

jacob navia

Ian said:

Well, You are a genius...
if you read the bit of my post you snipped - "try a group for your
platform, you'll get more help there." - you would see I was attempting
to help the OP.

You were attempting to help the original poster by
showing your ignorance.

Yes of course it helps him when you say you do not know the
subject matter.

Obviously, this proves that you are a genius.
Not on any platform I use, and that's quite a few.

Who cares?

It is supported by gcc and all the platforms gcc runs on,
supported by MSVC, supported by Watcom, Borland, lcc-win,
and what have you.

That is almost 100% of the market. Obviously you use
something else and never look into mainstream computing like
many regulars here.

Ignorance is a bliss!

I told you, you are a genius.
 
B

Bartc

jacob navia said:
Bartc wrote:

OBVIOUSLY you should save the registers ytour compiler thinks are
permanent

Under windows (where stdcall is commonly used) you should save
(I am assuming 64 bit CPU)

rsi
rdi
rbx
r12-r15
rbp

OK, for x86-32 then I have to worry about esi,edi,ebx.
you could just as well use the C calling convention. The registers to save
are THE SAME

The ASM is emitted by a compiler of mine from years back; I'm not going to
change it! I'll just stick in some bits of inline asm for now.

This is just a temporary measure until my project is 100% C. Or it will have
some ASM calling C which is a bit easier.
but you should just issue ret
and the called procedure adjusts the stack.

(That always seemed a crazy way to do things; one extra instruction /per
call/).
 
K

Keith Thompson

jacob navia said:
What piss me off of this regulars is that when they are proved
wrong they insist

Either I'm missing something, or you haven't done anything that
resembles proving me wrong.

I say __stdcall is platform-specific. You say it isn't. Fine, then
convince me that you're right. If you do, then I'll gladly admit it
(I admit to my mistakes here on a fairly regular basis).

What do you mean by "platform-specific", and how does that concept
*not* apply to __stdcall? Is it supported on all platforms?

I asked about "__stdcall"; you replied with macro named "STDCALL".
Are they intended to be the same thing?

Don't waste your time and ours by telling us that you're pissed off
because somebody disagrees with you. If you're right, demonstrate it.

(And by the way, this isn't about you; I'd say the same thing if
anyone else made the same claim.)
 
J

jacob navia

Bartc said:
OK, for x86-32 then I have to worry about esi,edi,ebx.

AND EBP!!!
The ASM is emitted by a compiler of mine from years back; I'm not going to
change it! I'll just stick in some bits of inline asm for now.

If your compiler was able to interface with outside code, it surely
saved those. It is very simple

push esi
push ebx
push edi

....

pop edi
pop ebx
pop esi

and you are all set

This is just a temporary measure until my project is 100% C. Or it will have
some ASM calling C which is a bit easier.


(That always seemed a crazy way to do things; one extra instruction /per
call/).

It saves 5% code space, it is very efficient.
 
R

Richard Tobin

If you use gcc you should

That sounds a bit platform-specific! But luckily I do use gcc.
#ifndef STDCALL
#define STDCALL __attribute__((stdcall))
#endif

I get:

foo.c:5: warning: 'stdcall' attribute directive ignored

Presumably this is an x86-only declaration.

-- Richard
 
F

Flash Gordon

Keith Thompson wrote, On 24/04/08 22:51:
What does defining "STDCALL" have to do with "__stdcall"? They're two
different identifiers, you know.

I suppose your point is that gcc supports a feature that's similar to
"__stdcall", but uses the syntax "__attribute__((stdcall))". So two
different platforms support a similar feature using radically
different syntax. If I were sufficiently motivated, I'm sure I could
find another platform that either supports it with yet another
different syntax, or doesn't support it at all.

"__stdcall" is platform-specific.

markg@hal02 ~ $ cat t.c
#ifndef STDCALL
#define STDCALL __attribute__((stdcall))
#endif
extern void STDCALL foo(void);
markg@hal02 ~ $ gcc -c t.c
t.c:4: warning: `stdcall' attribute directive ignored
markg@hal02 ~ $

Admittedly that is not an x86 based system. So just in case it is
specific to the processor type lets try on one of my x86 based systems...

On another system:
-bash-2.05b$ cc t.c
UX:i386acomp: ERROR: "t.c", line 4: error: Syntax error before or at: (
UX:i386acomp: ERROR: "t.c", line 4: error: cannot recover from previous
errors
-bash-2.05b$ cat tt.c
#ifndef STDCALL
#define STDCALL __stdcall
#endif
extern void STDCALL foo(void);
-bash-2.05b$ cc tt.c
UX:i386acomp: ERROR: "tt.c", line 4: error: syntax error, probably
missing ",", ";" or "="
UX:i386acomp: ERROR: "tt.c", line 4: error: Syntax error before or at: foo
UX:i386acomp: WARNING: "tt.c", line 4: warning: declaration missing
specifiers: assuming "int"
-bash-2.05b$


Nope, doesn't work on all x86 based systems either.

So Keith and Ian are correct to say it is platform specific.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,825
Latest member
VernonQuy6

Latest Threads

Top