Path: utzoo!attcan!utgpu!jarvis.csri.toronto.edu!cs.utexas.edu!wuarchive!udel!mmdf From: SUGGS%freddy.hac.com@cunyvm.cuny.edu Newsgroups: comp.sys.amiga Subject: Lattice C 5.04 bug Message-ID: <5453@nigel.udel.EDU> Date: 6 Dec 89 14:54:52 GMT Sender: mmdf@udel.EDU Lines: 56 I've discovered the following bug in Lattice C 5.04: When register variables are declared with an initial value, that value is also written onto the stack. That is, written over existing values on the stack, not pushed on the stack. Actually, the values are written to (A5), 4(A5) ..., but when a function reserves variable space on the stack via LINK A5,#nnnn the values that get overwritten are the saved value of A5 (for one register variable with an initial value) and the return address of the subroutine call (with a second register variable). source: test() { register int i = 1234; register int j = 5678; int k; /* so the function does a LINK A5,#nnnn if this line isn't here, A5 could be pointing anywhere, so you don't always see what gets trashed */ } generates the following assembly: LINK A5,#FFF4 CMPA.L __base(A4),A7 \ stack BCS.W __xcovf / overflow checking MOVEM.L D6-D7,-(A7) MOVE.L #4D2,D7 LEA 0(A5),A0 \ this code shouldn't be here! MOVE.L D7,(A0) / (overwrites saved value of A5) MOVE.L #162E,D6 LEA 4(A5),A1 \ ditto for this! MOVE.L D6,(A1) / (overwrites subroutine call return address) MOVEM.L (A7)+,D6-D7 UNLK A5 RTS It seems that the compiler doesn't take into account the fact that the variable is a register variable when handling the initial value of a declared variable. I say this because the code is similar to what is done when the variable is *not* a register variable (except the offset from A5 is negative to put it into the space reserved by the LINK instruction.) As I'm writing this, I just noticed that the LINK instruction also seems to be reserving space for all three variables, it should only need to be LINK A5,#-4 instead of -12. Hope this helps someone avoid the frustration I've been through. -Brian P.S. Why do they do LEA n(A5),A0 MOVE.L D7,(A0) instead of just MOVE.L D7,n(A5)