This patch fixes issues with a stack realignment.
MSVC maintains two frame pointers (ebx and ebp) for a realigned stack - one is used for access to function parameters, while another is used for access to locals. To support this the patch:
- adds an alternative frame pointer (ebx);
- considers stack realignment instructions (e.g. and esp, -32);
- along with CFA (Canonical Frame Address) which point to the position next to the saved return address (or to the first parameter on the stack) introduces AFA (Aligned Frame Address) which points to the position of the stack pointer right after realignment. AFA is used for access to registers saved after the realignment (see the test);
Here is an example of the code with the realignment:
struct __declspec(align(256)) OverAligned { char c; }; void foo(int foo_arg) { OverAligned oa_foo = { 1 }; auto aaa_foo = 1234; } void bar(int bar_arg) { OverAligned oa_bar = { 2 }; auto aaa_bar = 5678; foo(1111); } int main() { bar(2222); return 0; }
and here is the bar disassembly:
push ebx mov ebx, esp sub esp, 8 and esp, -100h add esp, 4 push ebp mov ebp, [ebx+4] mov [esp+4], ebp mov ebp, esp sub esp, 200h mov byte ptr [ebp-200h], 2 mov dword ptr [ebp-4], 5678 push 1111 ; foo_arg call j_?foo@@YAXH@Z ; foo(int) add esp, 4 mov esp, ebp pop ebp mov esp, ebx pop ebx retn
Btw, it seems that the code of x86AssemblyInspectionEngine has overgrown. I have some ideas how to refactor this, if you don't mind I can do it in the future?
D53086 also contains some discussion on the topic.