delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1997/10/22/12:31:45

From: ggerard AT larissa DOT cs DOT trinity DOT edu (Gregory Gerard)
Newsgroups: comp.os.msdos.djgpp
Subject: Weirdness: inline asm and inlining differences
Date: Wed, 22 Oct 1997 01:14:07 -0700
Organization: Flashnet Communications, http://www.flash.net
Lines: 85
Message-ID: <ggerard-ya02408000R2210970114070001@news.flash.net>
NNTP-Posting-Host: paltc7-77.flash.net
Mime-Version: 1.0
To: djgpp AT delorie DOT com
DJ-Gateway: from newsgroup comp.os.msdos.djgpp

Weird things (or rather, unexpected things) are happending with inlinging
code and specifically, inlining assembly inside of a function.

So I'm making my first steps screwing around with protected mode.  I'm
compiling a flat executable which gets loaded to a fixed point in memory
and then gets jumped into.  It's prefixed by some setup code (which
actually makes the transition to pmode, etc.) and then jumps to a flat code
area.  Not that this matters, but it's a backgrounder.

I'm constructing a bunch of primitives for manipulating the machine and
wanted to use inline functions which would contain inline assembly code.  I
figured I would get the same results as an inline asm statement but with
the benefit of typechecking.

For my example, I'm trying to load the IDT.  I assume someone has already
put me into a primitive protected mode (a loader) and that interrupts are
off.  The constants are coded just so I can pick them up more easily in the
disassembly.

typedef struct
{
   uint16   limit __attribute__ ((packed));
   uint32   offset   __attribute__ ((packed));
} mem48, *mem48Ptr;

mem48 theIDT = {0x3412, 0xefbeadde};

__inline__ void   lidt (mem48Ptr m);
inline void
lidt (mem48Ptr the)
{
   __asm__ __volatile__ ("lidt %0" : : "m" (the));
}

and now the reference to it:

void
theRef(void)
{
   lidt (&theIDT);
   __asm__ __volatile__ ("lidt %0" : : "m" (theIDT));
   __asm__ __volatile__ ("lidt %0" : : "m" (theIDT));
   __asm__ __volatile__ ("jmp . + 1024" : :);

}

produces assembly:

theRef:
   pushl %ebp
   movl %esp,%ebp
   subl $4,%esp
   movl $theIDT,-4(%ebp)
#APP
   lidt -4(%ebp)
   lidt theIDT
   lidt theIDT
   jmp . + 1024
#NO_APP
   leave
   ret


Questions:
1) Do I want to pass the address of the idt structure I've created or the
value?  I would think by value since that would seem to parallel the
straight inline asm case more closely when inline, but it does not produce
the same asm.

2) Why did GCC copy the address to the stack and then use the -4(%ebp) to
reference it?  It was clearly a global and the inlines did not require it
at all (they use the address of the global.)

3) Does anyone have a collection of macros/functions for dealing with the
machine at this level?  It's not so much a question of using asm for
efficiency, but because C cannot express the operation of the 386.  All the
tutorials I found seem more interested in the standard instructions used in
a more efficient manner rather than the system level functions.

4) Am I nuts for trying to do this with inline functions?  Should I just
use macros and be done with it?

thanks for the help.  I know this was rather lengthy, but I'm perplexed.

greg

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019