2010-06-03 58 views
1

我在VS中有一个函数,我将一个指针传递给该函数。然后我想将指针存储在寄存器中以进一步操作。你是怎样做的?内联汇编程序获取指针Visual Studio的地址

我已经试过

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(); 
} 

回答

3

选项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); 
} 

与Visual Studio 2008 SP1,单文件C++程序和调试版本,我步入F()结束时获得的寄存器窗口如下:

EAX = 004DF960 
EBX = 12345678 
ECX = 00000000 
EDX = 00000001 
ESI = 00000000 
EDI = 004DF884 
EIP = 003013C3 
ESP = 004DF7B8 
EBP = 004DF884 
EFL = 00000202 

查看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 
} 

步进到main()的末尾会得到以下寄存器值。 EAX获取数组中第一个元素的地址,而EBX获取其成员的值。

EAX = 00157038 
EBX = 000
ECX = 00004567 
EDX = 00000001 
ESI = 00000000 
EDI = 0047F800 
EIP = 001513C9 
ESP = 0047F734 
EBP = 0047F800 
EFL = 00000202 

魔法不在LEA指令本身。相反,看起来__asm指令根据是否使用MOV或LEA指令对待C/C++标识符。当MOV指令未注释时,这是同一程序的ASM转储。请注意,MOV指令如何获取[]的内容作为其参数(DWORD PTR),而LEA指令获取其偏移量。

; ... 

PUBLIC [email protected]@3PAHA  ; a 
_DATA SEGMENT 
[email protected]@3PAHA DDH ; a 
      DD 04567H 
_DATA ENDS 

; ... 

mov eax, DWORD PTR [email protected]@3PAHA 
lea eax, OFFSET [email protected]@3PAHA 
mov ebx, DWORD PTR [eax] 
mov ecx, DWORD PTR [eax+4] 

; ... 
+0

这的确行得通。对不起,我的问题实际上是我无法将指针加载到全局数组指针。你可以试试吗?我不想在栈上传递指针。 – Joe 2010-06-03 15:20:47

+0

不用担心。总之,使用LEA而不是MOV。我加入了答案。 – 2010-06-03 17:17:36

1

我不确定这是否正确,但您是否尝试将* p转换为int,然后加载该值?

void f(*p) { int tmp = (int)p; // asm stuff... }