I discovered this when trying to use the bp register within some
inline assembly code, compiled under a Release Build with /O2, and
noticing that it crashed the program.
Does anyone know why this happens?
#pragma optimize("y", on)
int f(int x)
{
int a = 8;
int b = 9;
return x + 7 + a + b;
}
int main()
{
f(78);
}
Trevor
It appears you need to include the "g" option in your #pragma.
--
Doug Harrison
Microsoft MVP - Visual C++
Doug,
Thanks for the response, but I can't make it work. I've tried setting
the /Gy and /G2 options. I've tried different combinations of #pragma
optimize with the "g" and "y" options. The below program crashes in
every case (create a console app with a single .c file, run with
VC6sp5, to reproduce).
Could you point out exactly what steps will make the compiler not use
the frame pointer, so code like below will work?
int f(int x)
{
int a = 8;
int b = 9;
_asm { mov bp, 0 }
return a + b + x;
}
int main()
{
f(78);
}
Trevor
I think you can do this!
The "Omit frame pointer" option is just a hint to the compiler that it
should avoid setting up frame pointers for functions that don't need
one. That doesn't free up the BP register, but only saves some code in
the affected functions.
Some functions (main(), perhaps?) actually *need* a frame pointer, and
will get one regardless of the options chosen.
Bo Persson
Should of course be: I think you can NOT do this!
Doh!
Bo Persson
Well, that's interesting. The __asm statement actually causes it to use the
frame pointer. Be that as it may, according to the documentation here, you
should preserve EBP around __asm blocks:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclang/html/_core_Using_and_Preserving_Registers_in_Inline_Assembly.asp?frame=true
<quote>
You should preserve other registers you use (such as DS, SS, SP, BP, and
flags registers) for the scope of the __asm block. You should preserve the
ESP and EBP registers unless you have some reason to change them (to switch
stacks, for example).
</quote>
I dunno, maybe tagging the function with __declspec(naked) could help you.
Mm, Okay. I guess it only does that for functions that don't access
locals? gcc's -fomit-frame-pointer will compile my f() function
accessing locals by offsets from SP. It will still crash, cause
main() uses BP, but I can work around that... I assumed VC would do
the same (access locals from SP), and it's a little disappointing it
doesn't. But I can live with it.
Thanks for the help!
Trevor