This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Calling convention that gets frame pointer register clobbered
- From: Etienne Lorrain <etienne_lorrain at yahoo dot fr>
- To: gcc at gcc dot gnu dot org
- Date: Fri, 19 Dec 2003 12:43:07 +0100 (CET)
- Subject: Re: Calling convention that gets frame pointer register clobbered
> : Does gcc support calling conventions that get the frame pointer register
> : clobbered?
>
> A related question: Is it possible, by inline assembler, to get GCC
> to save the frame pointer? I've tried to adding "ebp" to the clobbered
> list, with no effect. It is of course possible to add push/pop insns
> to the asm string, but that seems a bit risky, and does not look very
> pretty.
Another related question: Is it possible, by inline assembler, to get GCC
to save segment registers?
Not to manage them, just push before, pop after (but manage the stack
offset induced by push/pop).
- Real code use: interface with BIOS (who uses %es:%bp pointers and more)
- Why cannot easily do it by hand:
inline short fct (short param) {
short ret, tmp;
asm (
" pushl %es \n"
" int $0x15 \n"
" movw %es:3(%bp),%ax \n"
" movzbl %ah,%0 \n"
" popl %es \n"
: "=g" (ret), "=a" (tmp)
:
: "ebp"
};
return ret;
}
Does not work if "=g" (ret) is a stack reference because the
stack pointer is modified by push/pop %es - it does work for
anything else. This would always work:
inline short fct (short param) {
short ret, tmp;
asm (
" int $0x15 \n"
" movw %es:3(%bp),%ax \n"
" movzbl %ah,%0 \n"
: "=g" (ret), "=a" (tmp)
:
: "ebp", "es"
};
return ret;
}
Note also, while talking about asm()s, there seem to be a small
problem on asm's input/output of structures with their base address
in registers instead of memory:
You cannot compile the logical (%si containning the address of a
structure to be filled by the disk BIOS service int $0x13):
extern inline unsigned char
_EBIOSDISK_getparam (unsigned char disk, ebiosinfo_t *ebiosinfo,
unsigned char *status)
{
unsigned char carry;
asm (
" int $0x13 # _EBIOSDISK_getparam \n"
" mov %%ah,%1 \n"
" setc %0 \n"
: "=qm" (carry), "=qm" (*status)
: "a"((unsigned short)0x4800), "d" (disk), "S" (*ebiosinfo)
);
return carry;
}
You have to do (the "=m" may generate stange assembly):
extern inline unsigned char
_EBIOSDISK_getparam (unsigned char disk, ebiosinfo_t *ebiosinfo,
unsigned char *status)
{
unsigned char carry;
asm (
" int $0x13 # _EBIOSDISK_getparam \n"
" mov %%ah,%1 \n"
" setc %0 \n"
: "=qm" (carry), "=qm" (*status), "=m" (*ebiosinfo)
: "a"((unsigned short)0x4800), "d" (disk), "S" (ebiosinfo)
);
return carry;
}
The "=m" (*ebiosinfo) is needed to explain that it will modify
the content of the structure (which may be in the stack so
asm ("" : : : "memory") would not work).
I may be totally wrong but if the error message is removed, the
first asm() will/should behave as for function returning big structure
in GCC.
Happy Xmas anyways,
Etienne.
_________________________________________________________________
Do You Yahoo!? -- Une adresse @yahoo.fr gratuite et en français !
Yahoo! Mail : http://fr.mail.yahoo.com