Reputation: 1
Does the red zone exist in x86 ?
And even if not, can you explain to me by AMD64 ?
Where is the red zone ? WIKI: "the red zone is a fixed-size area in a function's stack frame below the current stack pointer" "current stack pointer": the meaning this area (128 bytes if i understand) always below of the updated stack pointer no distance ? or we have from the start some distance between, and this distance get closer and closer when i sub the esp ?
Should I give importance to the red zone ? always when i sub the esp ? like in push or call function or create locals (caller callee) ?
If I create local variables I will get to the red zone ? and is it dangerous ? (leaf/not leaf functions)
Does it matter if I call a leaf/not leaf function ?
To avoid this area should I do: sub esp, 128 ? and if yes wen ? before each sub the esp ?
#include <stdio.h>
int main() {
int x = 5, y, z;
// push
__asm {
sub esp, 4 // allocate cell on the stack (allocate static memory)
// we cant put 2 addresses on the address bus (we cant do: mov memory, memory)
mov eax, dword ptr [x] // save value of x on eax
mov [esp], eax // insert to the allocated cell value of eax (5 from x)
}
// peek
__asm {
mov eax, [esp] // the value of what is at the top of the stack
mov dword ptr [y], eax // copy to y
}
printf("y = %d\n", y);
// pop
__asm {
mov eax, [esp] // the value of what is at the top of the stack
mov dword ptr[z], eax // copy to z
add esp, 4 // deallocate cell on the stack (deallocate static memory)
}
printf("z = %d", z);
return 0;
}
or like this:
#include <stdio.h>
void f(int x) {
printf("%d\n", x);
}
void g() {
int x = 5;
f(x);
}
int main() {
__asm {
mov eax, 3
push eax
call f
add esp, 4
}
__asm { call g }
return 0;
}
Upvotes: 0
Views: 322
Reputation: 364287
No 32-bit x86 calling conventions use a red-zone, and MSVC can't target the x86-64 convention that does (AMD64 System V, used on all non-Windows systems).
Since you use push eax
(and stack args at all), your code can only compile for 32-bit mode, so you don't need to worry about a red-zone. That's true even if you were compiling with clang -fasm-blocks
e.g. for Linux to allow asm{}
syntax, instead of with MSVC or clang-cl
for Windows.
If you were writing different code with x86-64 64-bit registers, for a non-Windows OS with clang -fasm-blocks
or with normal GNU C inline asm (like asm("instructions" : "+r"(x) : "r"(y) : "rax")
), then you would need to worry about calling functions (or using the stack at all) from inside inline asm.
For that, see Calling printf in extended inline ASM for how to skip past the red-zone before using the stack, and how to declare clobbers on all the call-preserved registers.
Unfortunately there's no way to tell GCC/clang that you want to clobber the red-zone, so unless you build that with with -mno-red-zone
, you need to work around it.
Upvotes: 2