Re: getting symbolic C structure offsets (was: Re: C code validation service)

rfg@monkeys.com (Ronald F. Guilmette)
31 Jul 1996 19:29:39 -0400

          From comp.compilers

Related articles
C code validation service derek@knosof.co.uk (1996-07-15)
Re: C code validation service egbert@torch.timeplex.com (1996-07-19)
getting symbolic C structure offsets (was: Re: C code validation servi thornbur@theory.physics.ubc.ca (Jonathan Thornburg) (1996-07-27)
Re: getting symbolic C structure offsets (was: Re: C code validation s rfg@monkeys.com (1996-07-31)
| List of all articles for this month |

From: rfg@monkeys.com (Ronald F. Guilmette)
Newsgroups: comp.compilers
Date: 31 Jul 1996 19:29:39 -0400
Organization: Infinite Monkeys & Co.
References: 96-07-102 96-07-124 96-07-194
Keywords: C, assembler

Jonathan Thornburg <thornbur@theory.physics.ubc.ca> wrote:
>Stephen Egbert <egbert@torch.timeplex.com> asked for an
>| [...] extended preprocessor (GNU cpp or otherwise) that
>| can translate the C-styled structure offset for uses with assembly code
>| using symbolic offset.


I wrote a reply to an almost identical question which was raised in the
gnu.gcc.help newsgroup recently. I include it below in case it should
prove helpful. Note however that my response really only applies if
you happen to be using either the GNU C compiler or the GNU C++ compiler.


>Does anyone know of any extended preprocessor (GNU cpp or otherwise) that
>can translate the C-styled structure offset for uses with assembly code
>using symbolic offset.
>
>At the moment, only #define can replace any matching symbolic offset in
>a typical assembly opcode/operand(s).
>
>The idea is to maintain a single include file for uses for both C and
>assembly using GNU tools.


Regarding your question, I also came up against this same problem recently,
so I happen to know the answer... which is a bit obscure.


This issue comes up whenever you want to use the offset of some C-language
structure field inside some embedded assembly language code which itself
appears inside of one of gcc's `asm()' constructs.


The way to do this is to use the ANSI standard `offsetof' macro (as found
in your <stddef.h> system include file) to obtain the actual offset,
relative to the start of the structure, of the desired field. Fortunately,
the ANSI `offsetof' macro yields a value which gcc is smart enough to treat
as a compile-time constant (which is important, because the mechanism I
describe here would not work otherwise).


To do what you want to do, you must treat the value yielded by the ANSI-C
`offsetof' macro as just another C-language operand for your `asm()'
construct. (See the GCC manual for a description of how to use C-language
operands in asm() constructs.) That way you can (in effect) ``pass it in''
at compile-time so that it will become a part of the actual generated
assembly language code.


Here is a simple example for x86:


#include <stddef.h>


struct S { int field1; field2; };


void
func (struct S *ptr)
{
int field_val;


....
asm ("movl %2,%%eax; addl %c1(%%eax),%0"
: "=m" (field_val)
: "i" (offsetof (s, field2)), "m" (ptr)
: "%eax");
}


The code above should cause the value of ptr->field2 to be moved into the
variable `field_val'. It first moves the value of `ptr' into %eax and then
uses that as a base, along with the offsetof field2, to fetch the value of
ptr->field2.


This hunk of asm() code uses three C-language operands... designated as
%0, %1, and %2. Note however that (for the x86 case at least) we must
use the designator `%c1' rather than just `%1' when we want to have the
compiler generate... in the resulting asm code... the undecorated ASCII
representation of the numeric value of the offsetof `field2'. If we fail
to use that extra `c' character in the operand designator, then we will
get an extra dollar-sign character in there in front of the numeric value
which will represent the offset of field2, and that extra (unwanted) leading
dollar-sign character will make the GNU assembler rather unhappy. So you
must use the `c' modifier character in the operand name in this context.


I hope that the above example clarifies how to use C-language structure
offsets in embedded asm() constructs when using the GNU C/C++ compilers.
--


-- Ron Guilmette, Roseville, CA -------- Infinite Monkeys & Co. ------------
---- E-mail: rfg@monkeys.com ----------- Purveyors of Compiler Test Suites -
--


Post a followup to this message

Return to the comp.compilers page.
Search the comp.compilers archives again.