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: NNTP-Posting-Host: paltc7-77.flash.net Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp Precedence: bulk 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