Assembly Question

Started by
6 comments, last by Catafriggm 18 years, 10 months ago
For x86 assembly, what registers are guaranteed to be preserved across a function call, for __cdecl, __stdcall, and __fastcall?
Advertisement
esp
EBX, ESI, EDI, EBP. (I wouldn't include ESP - it's part of the function linkage scheme)
It's not a matter of "guaranteed to be preserved"; instead, the callee is by convention responsible for saving or not clobbering those registers. Since this is defined by the compiler and/or OS, it's Windows-specific.
E8 17 00 42 CE DC D2 DC E4 EA C4 40 CA DA C2 D8 CC 40 CA D0 E8 40E0 CA CA 96 5B B0 16 50 D7 D4 02 B2 02 86 E2 CD 21 58 48 79 F2 C3
The OP did say 'guaranteed to be preserved' but never said what OS or compiler was being used. So it's fair to say that ESP is the only one to be 'guaranteed to be preserved' otherwise the function would never return correctly. In VC the documentation does clearly state that you don't need to preserve any of the general purpose registers (EAX, EBX, ECX, EDX, ESI, EDI). ESP and EBP are usually preserved as they define stack frames, although a function could switch stacks (although that would be unlikely, so even ESP could get clobbered). The VC documentation does state that using EBX, ESI or EDI in an inline asm block will cause the compiler to add more code to save/restore those values. The documentation does state that the direction flag must be preserved accross inline assembly code.

So I guess the actual answer is 'none' as it is possible and legal to change any or all registers.

Skizz
Okay, next question: what calling conventions are defined for x64, and how do they work?
Raymond Chen on x64 calling conventions

On x86, I'm sure esi and edi have to be preserved. According Raymond ebx does as well. This is for Windows interfaces. Internall only functions can do pretty much anything depending on how smart your compiler is and how much information it has about the caller & callee. In general though internal functions will follow the same rules as external functions.
-Mike
I understand what you're saying about the architecture not guaranteeing anything, but "__cdecl" et al are MSC-specific (along with its clones), hence my assumption.
Think of it this way - irrespective of who saves the registers (your __asm block or the compiler), you know that any given externally visible function will not trash EBX etc. This is 'guaranteed' by the Win32 ABI.
E8 17 00 42 CE DC D2 DC E4 EA C4 40 CA DA C2 D8 CC 40 CA D0 E8 40E0 CA CA 96 5B B0 16 50 D7 D4 02 B2 02 86 E2 CD 21 58 48 79 F2 C3
Oooh. Thanks much, Mike.

This topic is closed to new replies.

Advertisement