[英]Defining a variable inside c++ inline assembly
Let's say we have the following c++ code: 假设我们有以下c ++代码:
int var1;
__asm {
mov var1, 2;
}
Now, what I'd like to know is if I didn't want to define var1 outside the __asm directive, what would I have to do to put it inside it. 现在,我想知道的是,如果我不想在__asm指令之外定义var1,我该怎么做才能将其放入其中。 Is it even possible?
可能吗
Thanks 谢谢
To do that, you'll need to create a "naked" method with _declspec(naked) and to write yourself the prolog and the epilog that are normally created by the compiler. 为此,您需要使用_declspec(naked)创建一个“裸”方法,并编写自己通常由编译器创建的序言和结语。
The aim of a prolog is to: 序言的目的是:
An epilog has to: 结语必须:
Here is a standard prolog 这是标准的序言
push ebp ; Save ebp
mov ebp, esp ; Set stack frame pointer
sub esp, localbytes ; Allocate space for locals
push <registers> ; Save registers
and a standard epilog: 和标准的结尾:
pop <registers> ; Restore registers
mov esp, ebp ; Restore stack pointer
pop ebp ; Restore ebp
ret ; Return from function
Your local variables will then begin at (ebp - 4)
and go downward to (ebp - 4 - localbytes)
. 然后,您的局部变量将从
(ebp - 4)
开始,然后向下至(ebp - 4 - localbytes)
。 The function parameters will start at (ebp + 8)
and go upward. 功能参数将从
(ebp + 8)
开始向上。
It' impossible to create a C variable in assembler: the C compiler has to know about the variable (ie its type and address), which means it has to be declared in the C code. 在汇编器中创建C变量是不可能的:C编译器必须知道该变量(即其类型和地址),这意味着必须在C代码中声明它。
What can be done is accessing symbols defined in assembler via extern
declarations in C. That won't work for variables with automatic storage duration, though, as these don't have a fixed address but are referenced relative to the base pointer. 可以做的是通过C中的
extern
声明访问在汇编器中定义的符号。但是,这对于具有自动存储持续时间的变量不起作用,因为这些变量没有固定的地址,而是相对于基本指针引用的。
If you don't want to access the variables outside of the asm
block, you can use the stack for storing assembler-local data. 如果您不想访问
asm
块之外的变量,则可以使用堆栈来存储本地汇编程序数据。 Just keep in mind that you have to restore the stack pointer to its previous value when leaving the asm
block, eg 请记住,离开
asm
块时,必须将堆栈指针恢复为其先前的值,例如
sub esp, 12 ; space for 3 asm-local 32bit vars
mov [esp-8], 42 ; set value of local var
[...]
push 0xdeadbeaf ; use stack
[...] ; !!! 42 resides now in [esp-12] !!!
add esp, 16 ; restore esp
If you don't want the relative addresses of the local variables to change whenever you manipulate the stack (ie use push
or pop
), you have to establish a stack frame (ie save the base of the stack in ebp
and address locals relative to this value) as described in cedrou's answer . 如果您不想每次操作堆栈时都改变局部变量的相对地址(即使用
push
或pop
),则必须建立一个堆栈框架(即将堆栈的基数保存在ebp
并相对于此值),如cedrou的答案中所述 。
Local variables are allocated and freed by manipulating the available space on the call stack via the ESP register, ie: 通过ESP寄存器在调用堆栈上操纵可用空间,可以分配和释放局部变量,即:
__asm
{
add esp, 4
mov [esp], 2;
...
sub esp, 4
}
Generally, this is better handled by establishing a "stack frame" for the calling function instead, and then access local variables (and function parameters) using offsets within the frame, instead of using the ESP register directly, ie: 通常,最好通过为调用函数建立一个“堆栈框架”,然后使用该框架内的偏移量访问局部变量(和函数参数),而不是直接使用ESP寄存器来更好地解决此问题,即:
__asm
{
push ebp
mov ebp, esp
add esp, 4
...
mov [ebp-4], 2;
...
mov esp, ebp
pop ebp
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.