Date: Thu, 15 Oct 1998 05:02:00 +0100 (BST) From: George Foot To: djgpp AT delorie DOT com Subject: Re: ASM Queries In-Reply-To: <36252536.148EA3@btinternet.com> Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII 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