February 5th, 2017, 09:15 AM
Borland C ASM Inline Coding Question
I was trying to code a put sprite routine using inline assembly to optimize the code, but I'm not sure if I have to restore all the registers you modify inside your routine before you return to C.
Is it necesary to restore them like you do on an Interrupt Service Routine? or does the C compiler takes care of this for you?
I was getting a "Divide error" but the routine worked ok, until I pushed and poped the DS register. Then everything worked fine, that's why I'm asking this...
February 5th, 2017, 11:32 AM
You are generally responsible for saving and restoring the state of the CPU not the compiler writer. If the compiler writer was to do it, he/she would end up saving and restoring everything - which would be quite an overhead (in terms of CPU cycles).
If you modify a register - the compiler could already be using this register itself and you would cause corruption. Some CPU registers are vitally important to the operation (e.g. DS, SP, BP, ...) others less so (e.g. AX) as they are used as temporary registers. Unfortunately, it can be the misuse of these registers that cause the unpredictable results.
Mor 'clever' compilers could look at register usage (at the assembly level or lower) and possibly decide to do some save/restore operations of its own?
My advice would be to leave the machine state in the condition you found it. Of course, read the manual to see what the compiler vendor says about code inserts (they may have some specific rules to make you life easier).
February 5th, 2017, 03:05 PM
Yes, it seems to depend a bit on what the compiler writers want.
Originally Posted by daver2
OpenWatcom doesn't seem to require you to restore any registers in an inline asm function.
With Borland I believe you need to restore *some* registers, but not necessarily all.
The best way to find out is to just write some asm, compile it, disassemble, and look at what the compiler puts around your code.
Experiment a bit with using different registers (also segment registers), and see how the compiler reacts.
I'm not sure, but I vaguely recall that Borland required you to preserve the segment registers, but not the regular registers (or at least not some of them, such as ax, bx, cx and dx).