__asm__ gcc调用内存地址

时间:2014-03-13 02:15:34

标签: c++ c memory gcc assembly

我有一个分配内存的代码,将一些缓冲区复制到分配的内存中,然后跳转到该内存地址。

问题是我无法跳转到内存地址。我使用gcc和__asm__,但我不能称之为内存地址。

我想做类似的事情:

address=VirtualAlloc(NULL,len+1, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
dest=strncpy(address, buf, len);

然后我想在ASM中这样做:

MOV EAX, dest
CALL EAX.

我尝试过类似的事情:

  __asm__("movl %eax, dest\n\t"
 "call %eax\n\t");

但它不起作用。 我该怎么办?

1 个答案:

答案 0 :(得分:2)

通常不需要为此使用asm,您只需通过一个函数指针,让编译器处理细节。 如果你坚持使用内联asm,你应该知道gcc inline asm是一个复杂的东西。另外,如果你希望函数返回,你应该确保它遵循调用约定,特别是它保留它应该的寄存器。

那就是说,这是措辞问题的答案:

int ret;
__asm__ __volatile__ ("call *%0" : "=a" (ret) : "0" (dest) : "ecx", "edx", "memory");

说明:

call *%0 = %0引用第一个替代参数,*是间接调用的标准gas语法

"=a" (ret) = eax寄存器中的输出参数应在块

之后分配给变量ret

"0" (dest) =与输出参数0在同一位置的输入参数(eax)应在块之前从dest加载

"ecx", "edx" =告诉编译器这些寄存器可能被asm块改变,按照正常的调用约定。

"memory" =告诉编译器asm块可能会对内存进行未指定的修改,所以不要缓存任何内容