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 -