www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1998/10/15/00:03:25

Date: Thu, 15 Oct 1998 05:02:00 +0100 (BST)
From: George Foot <george DOT foot AT merton DOT oxford DOT ac DOT uk>
To: djgpp AT delorie DOT com
Subject: Re: ASM Queries
In-Reply-To: <36252536.148EA3@btinternet.com>
Message-ID: <Pine.OSF.4.05.9810150446540.7625-100000@sable.ox.ac.uk>
MIME-Version: 1.0
Reply-To: djgpp AT delorie DOT com

On Wed, 14 Oct 1998, Thomas Harte wrote:

> 	However, having regular C code around the extended assembler in the
> same source files, I could quite do with using optimisations. Which of
> course do not just leave a set of defined integers in memory
> contiguously . . . . so the -4(%%eax) gets something completely random.
> At least, this is what I think is going on . . .

Quite likely.

> 	So what are my alternatives? Is there a standard way to do something
> like this such that the compiler understands I'd quite like the
> variables to be contiguous in memory - or should I be using different
> syntax?

    struct { int r, g, b, radd, gadd, badd; } variables;

then pass `&variables' to the program.  You'll want to pack the
struct too, strictly, or gcc is free to pad it out.

A better way is probably to use the "m" constraint.  It works
like "r" but allows gcc to leave the value in memory, and
retrieve it from there when you reference it.  You can in fact
specify multiple letters; gcc uses the first match it finds
IIRC, so if you put "rm", it will load into a register if
possible; if not, it will leave it in memory and load it when
you ask it to.  For immediate values you can use "i".  I don't
know too much about this, but here's an example (actually
compiled with Linux gcc, but should be the same under djgpp):

  int i = 1, j = 2;
  asm volatile (
                "movl %0, %%ecx\n\t"
                "movl %1, %%ecx\n\t"
                "movl %2, %%ecx\n\t"
                : : "r" (i), "mr" (j), "i" (4) : "ecx"
                );

The assembler block compiles to this:

        movl %edx, %ecx
        movl -8(%ebp), %ecx
        movl $4, %ecx

Note that the first value (i) was loaded into EDX since I said
`r'.  The second (j) was left in memory, because I said `m'
before `r'; this is nonsense really because `r' will only be
used if it runs out of `m' -- nonsense because `j' is already in
memory.  You'll want to put it the other way around, i.e. "rm",
so that gcc uses a register if possible, and if not it uses
memory.  The third parameter, 4, was placed into the code
immediately because I said `i'.  You can only do this with
immediate values, of course -- if you try it with a register
you'll get a compile-time error.

SET posted a short while ago an excellent summary of all the
constraints he could find out about from gcc's i386 machine
description.  Search the mail archives for this -- it's worth
having a copy of.

A third way you could achieve this sort of thing would be to
write the whole function in assembly language.  This may or may
not be convenient for you.  If you're interested in doing this,
I wrote a tutorial about it a while ago (but I can't remember
the URL).  Let me know if you want me to try harder to remember
it. ;)

> 	I'm fairly new to DJGPP inline, and I wasn't able to find anything in
> the FAQ (from faq202b - am I out of date?) nor the thing on Brennan's
> site . . . so thanks for any help. Feel free to forward.

Brennan's guide is an excellent way to get introduced to this,
but he doesn't mention all the constraints, obviously.  Combine
his guide with SET's summary of the constraints and you should
have everything you need to know.

-- 
george DOT foot AT merton DOT oxford DOT ac DOT uk

xu do tavla fo la lojban  --  http://xiron.pc.helsinki.fi/lojban/lojban.html

- Raw text -


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