Message-Id: <199808100754.IAA01503@sable.ox.ac.uk> Comments: Authenticated sender is From: George Foot To: GAMMELJL AT SLU DOT EDU Date: Mon, 10 Aug 1998 08:53:36 +0000 MIME-Version: 1.0 Content-type: text/plain; charset=US-ASCII Content-transfer-encoding: 7BIT Subject: Re: assembly language Reply-to: george DOT foot AT merton DOT oxford DOT ac DOT uk CC: djgpp AT delorie DOT com Precedence: bulk On 9 Aug 98 at 20:45, GAMMELJL AT SLU DOT EDU wrote: > When one compiles codename.cc with the -S -O2 switches, one gets > codename.cc in assembly language (codename.s). codename.s is easily > readable and can be edited with the DOS editor, a very nice feature. > When codename.cc contains a subroutine named sub (which may be used in > many programs) one sees that even though the optimizing switch -O2 has been > used there are small changes one can make in the assembly language for > sub (whose location in codename.s is clearly marked) which make the > executable a.exe produced by gxx codename.s run a little faster. > Now, one would like to use the modified assembly language for sub > in all future programs. That can be done in this way: Compile any > program.cc with gxx program.cc -S -O2, find sub in program.s, and > replace it with the modified assembly language for sub (one uses the > DOS editor to do that). Then gxx program.s. a.exe is a little faster. Be careful here. If your optimisations require looking at the code for the function and the code for calls to the function, and (for example) preserving extra registers inside the function, or failing to preserve some registers that the calling code doesn't need preserved, then your optimisations aren't really safe, and the problems they cause will be hard to debug. > But, it would be preferable to put the modified assembly language > for sub back in program.cc to start with (sub is contained in an include > file include file file.h so the programs requiring sub have #include > "file.h". One wants to put the assembly language in sub in file.h. > Here is the problem: the assembly language in sub.s is not exactly > like the AT&T assembly language conventions. There are no " ;" \ > on each line; there are only % symbols rather than %%; one has to > be cautious about the line numbers. It is extremely tedious to take > the .s assembly language and translate it back to AT&T conventions and > it is easy to make a mistake. You're wrong here; the code in a .S file is real AT&T-style assembler. It's just not in quite the same style as gcc's inline assembler. When you write the statement `asm (".....");', gcc inserts the given string into the assembly language output verbatim. This is the `basic' style of inline assembler; registers only have one % prefix (just like in .S files), and there are no inputs and outputs. If you want to write more than one instruction you must separate them with semicolons (`;') or line breaks. Since "....." obeys the rules of C strings you can use `\n' to break lines. The `\t' people sometimes put in results in more readable code in the .S file; it just indents the inlined code. The double % signs used in `extended' inline assembly are really just single % signs that have been escaped by another % sign. GCC needs to read through the code in extended inline assembly in order to replace certain pseudoregisters with real values, e.g. `%0', `%1', etc. This is how automatically assigned input and output registers work; it replaces these pseudo regsiters with its chosen x86 registers as it copies the code into the .S file. > What one would really like is to hand the .s code for sub back > to file.h with a compiler directive #replace subs assembly language > with the assembly language found in the file modifiedsub, say > #replace subasm modifiedsubasm > Maybe such a thing already exists and I just don't know about it. > I know it can be done: if I can do it with the DOS editor and compiler > can do it! ("and" in the line above ="the"). If the compiler can't > already do it, it would be a very small step forward if it were made > to. It is really only a matter of editing codename.s after it is > produced: I could almost do it myself if I knew what the hidden > end of line symbol in codename.s is, but the writers of the compiler > would know all of the tricks necessary to do it (how to read the > text file codename.s and replace subasm with modifiedsubasm. I don't think that would be a good idea; what if the code generated by the compiler changed? In any case, you can just write the routine in assembly language (and comment out the C version), like this: /* Prototype */ #ifdef __cplusplus extern "C" #endif int add (int, int); #ifndef USE_ASM /* C version */ int add (int a, int b) { return a+b; } #else /* assembly language version */ asm ("\n" ".global _add\n" /* This symbol should be exported */ " .p2align 2\n" /* Alignment speeds up calls */ "_add:\n" /* Use a label to mark the entry point */ " movl 4(%esp), %eax\n" /* Get first parameter in EAX */ " addl 8(%esp), %eax\n" /* Add on second parameter */ " ret\n" /* Return (integer result is in EAX) */ ); #endif Or you could just move it into a .S file of its own, of course. Note that since you're writing C++ code you'll need to prototype with `extern "C"', because the name of the function in the assembly language code is not mangled. I didn't include any debugging information in this function, and I also didn't use a frame pointer, but it's just an example. If you want more information about writing entire functions in assembly language (specifically in separate .S files, but it also works as above) please see: http://users.ox.ac.uk/~mert0407/asmfuncs.txt (which I've just updated with more complete and accurate information on parameters and return values). -- george DOT foot AT merton DOT oxford DOT ac DOT uk