Visual studio 内联汇编程序获取Visual Studio指针的地址

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

我在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, 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。我补充了答案。