Message-ID: <3277F652.1559@ananke.amu.edu.pl> Date: Thu, 31 Oct 1996 01:44:02 +0100 From: Mark Habersack Reply-To: grendel AT ananke DOT amu DOT edu DOT pl Organization: Home, sweet home MIME-Version: 1.0 To: John Sinnott CC: djgpp AT delorie DOT com Subject: Re: + 14649 optomizing cracks my code! References: <5558mf$ivj AT newshost DOT nmt DOT edu> Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit John Sinnott wrote: > > >I've been working with some VESA 2.0 functions and I've gotten a > >putpixel function to use the protected mode interface but whenever I use > >the -O? switch the code no longer works! What's wrong. Here's a > >snippet of the code... > > I have had similar problems, and am most interested in what the problem > may be. I am trying to compile a library with optimazition, and it compiles fine. > But when I compile other programs that use the library, they also compile fine but > crash at run time. I'm afraid I have missed the beginning of this thread, so I haven't seen the offending code. Anyway, a while ago I came accross the same problem. It turned out that the party to blame was myself. Why? Well the reason is simple. When gcc compiles code WITHOUT optimizations enabled it doesn't assume that any registers have a certain value at any specifiic moment. In other words, gcc doesn't assume intra-statement valiity of register contents. Thus, your code may freely modify any of the general registers and gcc will reload them after any statement/call which could modify them. Situation changes when you compile your app with any of the -O options turned on. This time, gcc optimizer tries to avoid reloading registers and assumes that they are preserved between statements. This is easy when gcc deals only with C/C++ code, as it generates the assembler output itself and has full control over what's happening. It's getting worse when the compiler encounters inline assembler code. It merely parses all the constrains, replacing references to them as appropriate. The compiler/optimizer, however, doesn't try to "understand" and optimize the code inside the 'asm' statement. So, if you modify any register and forget to reset its value, gcc doesn't know that and in good faith uses the value stored there by your inline code. Now imagine that you modified contents of the EDI register which was being used by gcc to keep a pointer to some malloc'ed buffer. When control leaves inline code and your C code tries to access the buffer, everything falls apart - SIGSEGV! To avoid all that mess use the fourth part of the 'asm' statement - 'modified registers'. Do it as follows: asm("mov $0, %%edi\n" . . : /* outputs */ : /* inputs */ : "%edi", ...); This tells gcc that you messed up with EDI register and that it might be not valid after execution of this code. gcc, being aware of that, saves EDI and restores it on exit from inline asm. That should do. -- ============================================================================ She nervously undressed in the dancing beams of the Fidra lighthouse Giving it all away before it's too late. She'll let her lover's tongue move in a warm wet circle, giving it all away and showing no shame. She'll take her mother's kiss on her first broken heart, a warm wet circle, she'll realise that she plays her part in a warm wet circle... ====================== http://ananke.amu.edu.pl/~grendel ===================