knudsen@ihwpt.UUCP (02/06/87)
Last nite I used the -ca switch to see how Microware C is screwing up the stack on goto's. First of all, this C does not use the stack for any control structures that I've examined. However, since any block of code in {} can introduce its own local vars, this C regards ANY goto as potentially hosing up the stack. Since the compiler is so nearsighted, it does certain things whenever it sees a goto or a label ("come-from"). The first technique used is basically OK. Before jumping on a goto, the compiler sets the stack back to when the function was entered, ie, it pops (nondestructively) the automatic vars plus any added in {} blocks. Each label entry puts the stack back to where it would be if that code were just flowed into (flowing jumps around the entry code). This overhead goes with every goto and label in your source code, but is just one LEAS instr. This simple scheme is used, for example, when doing a goto to another label within a list of cases in a switch, and probably any time that the label and goto are at the same level of {}, tho of course NOTHING needs to be done in such cases. But no real harm is done. But then they overthought the plumbing and thought up a fancier scheme that isnt needed and isn't even implemented correctly. In the case of my backwards goto out of a switch-case structure, they compute what the stack pointer was at function entry, but put it in the X register instead of S. That is, they do LEAX n,S where n is the current depth. Then at the label entry they do LEAS 0,X equivalent to TFR X,S when they *should* have done LEAS n,X So this explains why the stack pointer "walks" upward each time the goto recycles. Why Microware didn't stick with their first scheme I don't know. Looks like the second is an attempt to preserve the stack state at the goto, but I don't see why this should be needed. If they're smart enuf to understand why, why did they bugger up such a simple case? Until Microware fixes this (Level II maybe??), I suggest: (1) Don't use gotos across { or }. (2) If you get catastrophic failures for no good reason, look for violations of (1) and "instrument" the location of an auto variable with a printf to check for stack "walk". (3) Compile with the -a or -ac options and check your assembler input closely whenever you have any doubts about some non-trivial expression or statement. This compiler cannot be trusted! Someone reported trouble with &(array[i]) but I've had no trouble there. -- Mike J Knudsen ...ihnp4!ihwpt!knudsen "It's like trying to get to sleep at the Intergalactic Spaceport Hotel -- waiting for the being in the room above to drop the Nth shoe, and you don't even know what N is."