www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1996/10/30/20:32:49

Message-ID: <3277F652.1559@ananke.amu.edu.pl>
Date: Thu, 31 Oct 1996 01:44:02 +0100
From: Mark Habersack <grendel AT ananke DOT amu DOT edu DOT pl>
Reply-To: grendel AT ananke DOT amu DOT edu DOT pl
Organization: Home, sweet home
MIME-Version: 1.0
To: John Sinnott <jano AT arctic DOT nmt DOT edu>
CC: djgpp AT delorie DOT com
Subject: Re: + 14649 optomizing cracks my code!
References: <5558mf$ivj AT newshost DOT nmt DOT edu>

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
===================


- Raw text -


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