The alignment rules for structures and unions won't have changed.
So you code is probably making assumptions about the way that C is compiled that the optimiser doesn't have to obey.
Most likely because you are aliasing different types, search the web for 'strict aliasing'.
Your printf() calls are probably generating 'incorrect' output because 'char' is always converted to 'int' before being passed as a parameter and gets sign extended on the way ('unsigned char' is also converted to 'int' - not 'unsigned int').
My guess is that scanf() is doing odd things because you are passing the address of 'char' or 'short' variables without using the correct format and that adjacent memory locations are being overwritten. I avoid scanf(), typically using strtoul() to parse numbers.
I would also completely bypass all of the 'file' interfaces when writing to flash on an embedded system. You just need to expose and appropriate interface that directly accesses the underlying memory - there is no need for multiple layers of abstraction.