There are no generally-applicable rules. About the only thing you can count on is that instructions within a single thread will execute in sequence relative to each other(*). The relative sequencing of instructions from multiple threads is entirely up to the OS, and can vary from OS to OS, from one type of hardware to another, or from one moment to the next. On a multicore CPU, it doesn't even really make sense to talk about the sequencing of instructions from different threads, since both threads can be (and often are) executing instructions at literally the exact same instant, each on a different core.
And of course the order in which the instructions execute is not at all guaranteed to be the same as the order in which the text emerges from the stdout stream. Some stdio implementations may serialize the calls that add text to the stdout stream, while others may not, meaning that you might not necessarily see the expected output lines at all, or they might be munged in unexpected or unpredictable ways.
Non-synchronized/non-deterministic behavior is a big can of worms; a very large portion of multithreaded programming is learning how and when to synchronize execution so that you get reliable results 100% of the time (and not just 99% of the time).
(*) Actually, you can't even count on that, since the compiler and/or the CPU might rearrange them to make the code execute more efficiently. But at least they are constrained to only rearrange them in ways such that the rearranged instructions' observable behavior is the same as it would have been if the instructions were still in their original sequence. Note that these constraints only apply to interactions with other code within the same thread, though; when it comes to unsynchronized interactions with other threads, all bets are off.