比方说,我们有以下的C++代码:定义变量中的C++内联汇编
int var1;
__asm {
mov var1, 2;
}
现在,想我所知道的是,如果我不想定义__asm指令外VAR1,我需要做些什么才能把它放进去。它甚至有可能吗?
由于
比方说,我们有以下的C++代码:定义变量中的C++内联汇编
int var1;
__asm {
mov var1, 2;
}
现在,想我所知道的是,如果我不想定义__asm指令外VAR1,我需要做些什么才能把它放进去。它甚至有可能吗?
由于
要做到这一点,您需要使用_declspec(裸体)创建一个“裸”方法,并编写通常由编译器创建的序言和结语。
一个序言的目的是:
的结语有:
这里预留空间是一个标准的序言
push ebp ; Save ebp
mov ebp, esp ; Set stack frame pointer
sub esp, localbytes ; Allocate space for locals
push <registers> ; Save registers
和一个标准的结尾处理:
pop <registers> ; Restore registers
mov esp, ebp ; Restore stack pointer
pop ebp ; Restore ebp
ret ; Return from function
你的局部变量将从(ebp - 4)
开始,然后下降到(ebp - 4 - localbytes)
。功能参数将从(ebp + 8)
开始并向上。
它不可能创建汇编一个C变量:C编译器必须知道有关变量(即,其类型和地址),这意味着它具有在C代码中声明。
可以做的是通过C中的extern
声明访问汇编程序中定义的符号。这对于具有自动存储持续时间的变量来说不起作用,尽管这些变量没有固定的地址,而是相对于基址指针。
如果您不想访问asm
块之外的变量,则可以使用堆栈来存储汇编程序本地数据。请记住,你必须堆栈指针恢复到以前的值在离开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
如果你不想局部变量的相对地址改变,只要你操作堆栈(即使用push
或pop
),则必须按照cedrou's answer中所述建立堆栈帧(即,将堆栈的基址保存在ebp
中,并将地址相对于此值保存)。
局部变量分配和释放由通过ESP寄存器操作的调用堆栈上的可用空间,即:
__asm
{
add esp, 4
mov [esp], 2;
...
sub esp, 4
}
一般来说,这是通过建立一个“堆栈帧”为调用函数更好地处理反而,然后访问使用偏移局部变量(和功能参数)的框架内,而是采用了ESP直接注册,即:
__asm
{
push ebp
mov ebp, esp
add esp, 4
...
mov [ebp-4], 2;
...
mov esp, ebp
pop ebp
}
确定子ESP,3会给空间3 32位瓦尔?我的想法是,对于每个32位变量,我必须从esp中取4个变量。 – 2009-09-08 21:47:51
至少C++在内部定义如下:var_4 = dword ptr -4 – 2009-09-08 21:48:27
你是对的 - 不应该在深夜回答问题;) – Christoph 2009-09-08 22:53:44