Date: Tue, 15 Aug 95 03:04 MDT From: mat AT ardi DOT com (Mat Hostetter) To: "A.Appleyard" Cc: djgpp AT sun DOT soe DOT clarkson DOT edu Subject: Re: inline asm? References: >>>>> "A" == A Appleyard writes: A> othe AT df DOT lth DOT se (Ola Theander) wrote:- >> I like to know if it's possible to include asm code in the C >> source code using djgpp. >/* These swop the registers with the (values currently in _ax etc) */ >#define __SR() /* save the registers */ ({asm("xchgl %eax,__ax"); \ > asm("xchgl %ebx,__bx"); asm("xchgl %ecx,__cx"); asm("xchgl %edx,__dx"); \ > asm("xchgl %esi,__si"); asm("xchgl %edi,__di"); asm("xchgl %ebp,__bp"); }) I'm generally not one for net.flaming, but it irks me when people answer questions with examples which are completely broken. This is an *extremely* bad example of how to use gcc inline asm, for several reasons: 1) You must tell gcc about input and output values, and which registers get clobbered. If you hide that information from gcc, and just smash registers anyway (as this example does), it's quite possible that your program won't work. gcc will allocate variables to those registers, with no idea they are being smashed. 2) This code contains a sequence of contiguous asm statements, which is a bad idea if you really want the asms to be contiguous. Granted, I think this code will happen to work under gcc since asm's with no specified output operands are implicitly volatile. Anyway, the correct way to write a contiguous block of x86 instructions is to use one asm listing multiple x86 instructions. 3) This code uses the hardcoded names "__ax", etc. for asm symbols, which aren't guaranteed to be correct; for example, on a Linux ELF system those symbols would have one too many underscores. Instead, you should use those variables as operands to the asm, and let gcc do the right thing. 4) This code hides from gcc the fact that __ax, etc. are really input and output parameters. gcc is free to assume that those variables do not get modified by this asm, and optimize accordingly. 5) It's hard to imagine a situation where you'd ever save and restore all the registers like this. Of what possible use is it? If subsequent asms use certain fixed registers, just tell gcc what they need and let gcc deal with saving and restoring registers as needed. 6) xchgl is really slow, at least on the Pentium. >inline uns long _farpeekl(uns short selector, uns long offset) {uns long R; > asm("movw %0,%%fs" : : "r" (selector)); > asm(".byte 0x64\n" " movl (%1),%0" : "=r" (R) : "r" (offset)); return R;} asm like this is inefficient, as it forces the offset to be loaded into a register, even if that offset is a constant or an expression that would be more efficiently expressed with a general addressing mode, e.g. "16(%eax,%ebx,4)". -Mat