This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]