Visual studio 内联汇编程序获取Visual Studio指针的地址
我在VS中有一个函数,我在其中传递一个指向该函数的指针。然后我想将指针存储在寄存器中以进一步操作。你是怎么做到的 我试过了Visual studio 内联汇编程序获取Visual Studio指针的地址,visual-studio,visual-c++,assembly,inline-assembly,Visual Studio,Visual C++,Assembly,Inline Assembly,我在VS中有一个函数,我在其中传递一个指向该函数的指针。然后我想将指针存储在寄存器中以进一步操作。你是怎么做到的 我试过了 float __declspec(align(16)) x[16] = { 0.125000, 0.125000, 0.125000, 0, -0.125000, 0.125000, -0.125000, 0, 0.125000, -0.125000, -0.125000, 0, -0.125000, -0.125000, 0.125000
float __declspec(align(16)) x[16] =
{
0.125000, 0.125000, 0.125000, 0,
-0.125000, 0.125000, -0.125000, 0,
0.125000, -0.125000, -0.125000, 0,
-0.125000, -0.125000, 0.125000, 0
};
void e()
{
__asm mov eax, x // doesn't work
__asm mov ebx, [eax]
}
void f(float *p)
{
__asm mov eax, p // does work
__asm mov ebx, [eax]
}
int main()
{
f(x);
e();
}
选项1实际上似乎效果不错。考虑下面的程序:
#include <stdio.h>
void f(int *p) {
__asm mov eax, p
__asm mov ebx, [eax]
// break here
}
void main()
{
int i = 0x12345678;
f(&i);
}
看看EAX、EBX和ESP中的值,这似乎是一个很好的证据,表明您确实拥有EAX中所需的指针。EAX中的地址比ESP中的地址略高一点,表明它比堆栈高一帧。加载到EBX中的解引用值表明我们得到了正确的地址
加载全局文件的地址有细微的不同。以下示例使用LEA指令完成任务
#include <stdio.h>
int a[] = { 0x1234, 0x4567 };
void main()
{
// __asm mov eax, a ; interpreted as eax <- a[0]
__asm lea eax, a ; interpreted as eax <- &a[0]
__asm mov ebx, [eax]
__asm mov ecx, [eax+4]
// break here
}
魔力不在LEA指令本身。相反,似乎_asm指令根据使用的是MOV指令还是LEA指令,对C/C++标识符的处理方式有所不同。以下是当MOV指令未注释时,同一程序的ASM转储。请注意,MOV指令如何获取[]的内容作为其参数(DWORD PTR),而LEA指令如何获取其偏移量
; ...
PUBLIC ?a@@3PAHA ; a
_DATA SEGMENT
?a@@3PAHA DD 01234H ; a
DD 04567H
_DATA ENDS
; ...
mov eax, DWORD PTR ?a@@3PAHA
lea eax, OFFSET ?a@@3PAHA
mov ebx, DWORD PTR [eax]
mov ecx, DWORD PTR [eax+4]
; ...
选项1实际上似乎效果不错。考虑下面的程序:
#include <stdio.h>
void f(int *p) {
__asm mov eax, p
__asm mov ebx, [eax]
// break here
}
void main()
{
int i = 0x12345678;
f(&i);
}
看看EAX、EBX和ESP中的值,这似乎是一个很好的证据,表明您确实拥有EAX中所需的指针。EAX中的地址比ESP中的地址略高一点,表明它比堆栈高一帧。加载到EBX中的解引用值表明我们得到了正确的地址
加载全局文件的地址有细微的不同。以下示例使用LEA指令完成任务
#include <stdio.h>
int a[] = { 0x1234, 0x4567 };
void main()
{
// __asm mov eax, a ; interpreted as eax <- a[0]
__asm lea eax, a ; interpreted as eax <- &a[0]
__asm mov ebx, [eax]
__asm mov ecx, [eax+4]
// break here
}
魔力不在LEA指令本身。相反,似乎_asm指令根据使用的是MOV指令还是LEA指令,对C/C++标识符的处理方式有所不同。以下是当MOV指令未注释时,同一程序的ASM转储。请注意,MOV指令如何获取[]的内容作为其参数(DWORD PTR),而LEA指令如何获取其偏移量
; ...
PUBLIC ?a@@3PAHA ; a
_DATA SEGMENT
?a@@3PAHA DD 01234H ; a
DD 04567H
_DATA ENDS
; ...
mov eax, DWORD PTR ?a@@3PAHA
lea eax, OFFSET ?a@@3PAHA
mov ebx, DWORD PTR [eax]
mov ecx, DWORD PTR [eax+4]
; ...
我不确定这是否正确,但您是否尝试过先将*p强制转换为int,然后再加载该值
void f(*p)
{
int tmp=(int)p;
//asm的东西。。。
}
我不确定这是否正确,但您是否尝试过先将*p强制转换为int,然后再加载该值
void f(*p)
{
int tmp=(int)p;
//asm的东西。。。
}
这确实有效。抱歉,我的问题实际上是无法将指针加载到全局数组指针。你能试试吗?我不想在堆栈上传递指针。不用担心。简而言之,使用LEA而不是MOV。我在答案上加了一句。这确实有效。抱歉,我的问题实际上是无法将指针加载到全局数组指针。你能试试吗?我不想在堆栈上传递指针。不用担心。简而言之,使用LEA而不是MOV。我补充了答案。