But your example misses a lot....
1) Which of those registers does the ABI demand should be restored?
2) Even if the ABI demands that, that does not mean that the code requires it.
For the code to require this, your LCL must be build with optimization, so it relies on registers. And even then, it must on further more rely on exactly those (or some of them).
If the code never relied on those registers, then it won't crash.
And, in your case, that reliance would have to be in the *caller* of the code that has the "try except" that catches this.
I.e. way up the callstack is a try...except. All the callers down to there, don't get executed on the way back. So for them, its not important what happened to the registers.
Then in one procedure the try...except happens. When the "except" block ends, that is the earliest where any register may be expected back to its original value.
Exception handling depends on the Target. On Windows this would be SEH.
I just googled: does SEH restore cpu registers
And Google's AI says: yes, it does.
However, in your code there may still be luck involved.
If you looked at asm you would have seen mnemonics like sehpush. Those describe to the assemble what info to leave for the exception unwinding code. => your asm does not have that. I don't know if it should (if it was on Windows). But that would only matter if those regs weren't saved in any other method between yours and the try...except.
And other targets? I don't know, exceptions are handled by other means.