我有一个分配内存的代码,将一些缓冲区复制到分配的内存中,然后跳转到该内存地址。
问题是我无法跳转到内存地址。我使用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");
但它不起作用。 我该怎么办?
答案 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块可能会对内存进行未指定的修改,所以不要缓存任何内容