Avr-gcc does not compile correctly without optimizations, but works (badly) with -Os
You'll need to inspect the output of avr-objdump to see what exact instructions were generated for your code. Incidentally, it would be helpful to include your C code in the disassembly via avr-objdump -S main.elf &gt; main.s. I doubt that the whole program becomes different when you replace the 0x1F constant by 0x3F, isolating differences in the listing and analyzing them carefully would be your next step.

Such analysis is about as far as you can get without proper development tools. Getting a debugger or a simulator would save you a lot of effort which is required when you're limited to static listing analysis.

PS: I assume here that you don't get any compiler warnings during compilation. If you have any, fixing those should be your first priority. Modern compilers do a pretty good job at informing you about subtle errors which may be hard to find otherwise.