www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1995/08/15/06:24:40

Date: Tue, 15 Aug 95 03:04 MDT
From: mat AT ardi DOT com (Mat Hostetter)
To: "A.Appleyard" <A DOT APPLEYARD AT fs2 DOT mt DOT umist DOT ac DOT uk>
Cc: djgpp AT sun DOT soe DOT clarkson DOT edu
Subject: Re: inline asm?
References: <A805AB45FAE AT fs2 DOT mt DOT umist DOT ac DOT uk>

>>>>> "A" == A Appleyard <A DOT APPLEYARD AT fs2 DOT mt DOT umist DOT ac DOT uk> 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

- Raw text -


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