www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1993/04/02/10:29:02

Date: Fri, 2 Apr 93 09:14:27 CST
From: (csaba AT vuse DOT vanderbilt DOT edu) <csaba AT vuse DOT vanderbilt DOT edu>
To: MVICUNA AT delphi DOT com
Cc: djgpp AT sun DOT soe DOT clarkson DOT edu
Subject: Re: Inline Assembly

On 02 Apr 1993 00:52:50 -0500 (ES,
  <MVICUNA AT delphi DOT com> writes:

>
>
>  Hope I'm not stating the obvious here.
>
>  asm(asmbler statements : outputs : inputs : registers directly accessed);
>
>  the first part is simple if you know how to use the asm statement.
>
>  Outputs, are more tricky.  The compiler assumes that only these variables
>are modified by the asm statement.  Its parameter number is %0.
>
>  Inputs are kinda obvious, there numbers start at %1 ... %N.

You can have more than one output parameters, i.e:

  %0 ... %K   => outputs
  %K+1 ... %N => inputs

>
>  The registers directly accessed, doesn't seem to work for me.  If anyone
>know where I could find out if this is a bug or what??

  You have to use the 16 BIT (!!!!) register names without '%'. I.e:

  int quotient,remainder,nominator,divisor;
  asm("movl %2,%%eax; movl %3,%%ebx; \
      divl %%ebx; \
      movl %%eax,%0; movl %%edx,%1"
      : "=g" (quotient), "=g" (remainder)
      : "g"  (nominator), "g" (divisor)
      : "ax", "bx", "dx"
  );

The above will work.

>  inputs/outputs take the form:
>  "(type of register" (variable name) , ....
>
>  I only know how to use 2 types of variables, you'd need the Gas Sources
>to look up the i386 machince desciption.
>
> the first type is '"r" foobar' which tells the compiler to put foobar
>into a register if its not all ready in one.
>
>  the other is '"g" foobar' which, I think, tells the compiler to use its
>own guess as the best way to use foobar in the asm statement.  If its
>allready in a register put it there, or if you don't need to load it it doesn't
>you just hafta trust the compiler.
>
>
>  The example the use in the extend.tex file which is usefull is this.
>
>  asm("addl %1,%2" : "2=" result : "g" op1, "r" op2 );
>
>  result holds the value of the addl instruction.
>
>  op2 and op1 are not changed, don't know if that is bug free though.
>
>  the '"2=" result' tells that same register holds the info for both result
>and the third paramenter, second input.
>
>  you can also put in register names like '"%eax" foobar' if you want.  Thats
>a throw back to the older compiler I assume.
>
>  If you directly access a register in your asm statement, asm("xorl %eax,%eax");
>, the compiler will notice that and deal with eax being wiped out.

I don't think this is true. You HAVE TO TELL the compiler on the third : 
field the registers whose contents are changed by your instruction sequence.

>
>  BUT it can't handle things like asm("imul %ebx");.  IT won't know
>that %eax and %edx have been changed.  Thats bad.  I tried what it
>says in the Docs, but it don't work.

See above. It works. 


A few additional things:

If any of the ':' fields are used, the register names in the assembly 
instruction string have to be preceeded with two %-s. Otherwise only one % 
is needed. It is because in the presence of :-s GCC runs the assembly 
string through a printf-like formatter, and GAS unfortunately uses the 
same format character (%) as the register name prefix.

The 'volatile' keyword after the 'asm' simply tells the optimizer that it 
is not permitted to move around (or possibly eliminate) the instruction 
sequence. 

>
>  Hopes this helps someone.
>
>Thanks,
>MarkV.

Csaba Biegl
csaba AT vuse DOT vanderbilt DOT edu

- Raw text -


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