1. Asm called by c_func
- Posted by Larry Miller <larrymiller at sasktel.net> Apr 24, 2007
- 529 views
I know that an assembly routine called by call() must preserve all registers. What registers, if any, must be preserved if the routine is called by c_func? Am I correct in assuming that the return value will be in the EAX register? From examples I have determined the calling conventions. Larry Miller
2. Re: Asm called by c_func
- Posted by Bernie Ryan <xotron at bluefrog.com> Apr 24, 2007
- 529 views
Larry Miller wrote: > > I know that an assembly routine called by call() must preserve all registers. > What registers, if any, must be preserved if the routine is called by c_func? > Am I correct in assuming that the return value will be in the EAX register? > From examples I have determined the calling conventions. > Hi Larry You need to preserve any register that your internal assembly code uses so that you can restore them to their original values. The EAX returns with whatever your internal assembly code places in it. This could be a flag or a 32-bit value or a 32-bit pointer. Bernie My files in archive: WMOTOR, XMOTOR, W32ENGIN, MIXEDLIB, EU_ENGIN, WIN32ERU, WIN32API Can be downloaded here: http://www.rapideuphoria.com/cgi-bin/asearch.exu?dos=on&win=on&lnx=on&gen=on&keywords=bernie+ryan
3. Re: Asm called by c_func
- Posted by Robert Craig <rds at RapidEuphoria.com> Apr 24, 2007
- 515 views
Larry Miller wrote: > I know that an assembly routine called by call() must preserve all registers. > What registers, if any, must be preserved if the routine is called by c_func? > Am I correct in assuming that the return value will be in the EAX register? > From examples I have determined the calling conventions. I think (but I'm not 100% sure) that with either the cdecl or stdcall conventions, EAX, ECX and EDX need not be saved/restored by the called subroutine. I think EAX is often used to hold the return value, if any. Here are some rough notes that I made on calling conventions several years ago. Unfortunately, I don't think Watcom follows the cdecl conventions exactly the same as the other C compilers do. In general, I don't think it's wise to assume too much detail about these conventions, if you don't really have to. Calling Convention Info ======================= Common to BOTH __cdecl AND __stdcall: 1. All symbols are preceded by an underscore character. 2. Arguments are pushed on the stack from right to left. That is, the last argument is pushed first. 3. Registers EAX, ECX and EDX are not saved and restored when a call is made. __cdecl: - The calling routine will remove the arguments from the stack. - Floating-point values are returned in the same way as structures. When a structure is returned, the called routine allocates space for the return value and returns a pointer to the return value in register EAX. __stdcall: - All C symbols (extern "C" symbols in C++) are suffixed by "@nnn" where "nnn" is the sum of the argument sizes (each size is rounded up to a multiple of 4 bytes so that char and short are size 4). When the argument list contains "...", the "@nnn" suffix is omitted. - The called routine will remove the arguments from the stack. - When a structure is returned, the caller allocates space on the stack. The address of the allocated space will be pushed on the stack immediately before the call instruction. Upon returning from the call, register EAX will contain address of the space allocated for the return value. Floating-point values are returned in 80x87 register ST(0). Regards, Rob Craig Rapid Deployment Software http://www.RapidEuphoria.com
4. Re: Asm called by c_func
- Posted by Larry Miller <larrymiller at sasktel.net> Apr 24, 2007
- 520 views
- Last edited Apr 25, 2007
Thanks to Bernie and Robert. I suspected that all registers should be saved but was not certain. Bit.e by Juergen Luethje in the recent contributions uses ECX but does not save it. Larry Miller
5. Re: Asm called by c_func
- Posted by Juergen Luethje <j.lue at gmx.de> Apr 25, 2007
- 514 views
Larry Miller wrote: > Thanks to Bernie and Robert. I suspected that all registers should be saved > but was not certain. Bit.e by Juergen Luethje in the recent contributions uses > ECX but does not save it. Yes, since I have the same information as Rob regarding this point. Also, I never have encountered any problem by not saving the values of AX, CX, DX (in the old 16-bit world) or EAX, ECX, EDX respectively. Regards, Juergen
6. Re: Asm called by c_func
- Posted by Bernie Ryan <xotron at bluefrog.com> Apr 25, 2007
- 512 views
Juergen Luethje wrote: > > Larry Miller wrote: > > > Thanks to Bernie and Robert. I suspected that all registers should be saved > > but was not certain. Bit.e by Juergen Luethje in the recent contributions > > uses > > ECX but does not save it. > > Yes, since I have the same information as Rob regarding this point. > Also, I never have encountered any problem by not saving the values of > AX, CX, DX (in the old 16-bit world) or EAX, ECX, EDX respectively. > Hi Juergen If you are mixing programming langauges with assembler and the langauge is using fast calls the parameters are pass back and forth in the registers. If you destroy a registers you may crash the code. You should always preserve any register that you use. If you use a register that changes the direction flag you should do a CLD a clear the direction flag before you return because some lanagauges are depending on the direction flag to be clear. If your not concerned about speed you can use the pushad / popad to preserve the 32bit registers. pushfd / popfd to preserve the flag registers. Or preserve just the registers that you disturb. This being in addition to returning with stack be setup in the correct condition. Bernie My files in archive: WMOTOR, XMOTOR, W32ENGIN, MIXEDLIB, EU_ENGIN, WIN32ERU, WIN32API Can be downloaded here: http://www.rapideuphoria.com/cgi-bin/asearch.exu?dos=on&win=on&lnx=on&gen=on&keywords=bernie+ryan
7. Re: Asm called by c_func
- Posted by Juergen Luethje <j.lue at gmx.de> Apr 25, 2007
- 503 views
Bernie wrote: > Juergen Luethje wrote: > >> Larry Miller wrote: >> >>> Thanks to Bernie and Robert. I suspected that all registers should be saved >>> but was not certain. Bit.e by Juergen Luethje in the recent contributions >>> uses >>> ECX but does not save it. >> >> Yes, since I have the same information as Rob regarding this point. >> Also, I never have encountered any problem by not saving the values of >> AX, CX, DX (in the old 16-bit world) or EAX, ECX, EDX respectively. >> > > Hi Juergen > > If you are mixing programming langauges with assembler and the langauge > is using fast calls the parameters are pass back and forth in the registers. > > If you destroy a registers you may crash the code. Larry had asked a concrete question: | What registers, if any, must be preserved if the routine is called by c_func? In an assembler routine that is called by c_func(), the parameters are passed on the stack. This is the reason why inside the routine we can refer to the parameters e.g. with [esp+4]. > You should always preserve any register that you use. Nope. > If you use a register that changes the direction flag you should > do a CLD a clear the direction flag before you return because > some lanagauges are depending on the direction flag to be clear. Registers do not change the direction flag at all. Certain _ASM commands_ change the direction flag. This is a completely different thing, and has nothing got to do with our question here. > If your not concerned about speed you can use the > pushad / popad to preserve the 32bit registers. This is necessary for implementing a custum interrupt handler or something. Here it is not only not required, but it would destroy the functions. The functions _have to_ change the contents of EAX, because they store the return value there! > pushfd / popfd to preserve the flag registers. > > Or preserve just the registers that you disturb. I'm not "disturbing" anything. The code in 'bit.e' as it is currently is correct. > This being in addition to returning with stack be setup in the correct > condition. <quote> 32 bit Windows, Linux, BSD, Mac OS ---------------------------------- Scratch registers : EAX, ECX, EDX, ... Callee-save registers: EBX, ESI, EDI, EBP [...] Scratch registers are registers that can be used for temporary storage without restrictions (also called caller-save or volatile registers). Callee-save registers are registers that you have to save before using them and restore after using them (also called non-volatile registers). </quote> Reference: http://www.agner.org/optimize/calling_conventions.pdf Chapter 6, Register usage Regards, Juergen
8. Re: Asm called by c_func
- Posted by Bernie Ryan <xotron at bluefrog.com> Apr 25, 2007
- 547 views
- Last edited Apr 26, 2007
Sorry I even tried to help. Bernie My files in archive: WMOTOR, XMOTOR, W32ENGIN, MIXEDLIB, EU_ENGIN, WIN32ERU, WIN32API Can be downloaded here: http://www.rapideuphoria.com/cgi-bin/asearch.exu?dos=on&win=on&lnx=on&gen=on&keywords=bernie+ryan