【问题标题】:asm block in c++ as a macroc++中的asm块作为宏
【发布时间】:2013-05-27 02:20:56
【问题描述】:

我想编写一个宏,它可以将所有内容都转换为 void*,甚至是成员函数。 代码如下:

#define toVoidStar(xx,yy)\
    __asm push ecx; \
    __asm mov ecx, yy; \ 
    __asm mov [xx], ecx; \ 
    __asm pop ecx;

当我“调用它”时它给出错误:错误 C2017:非法转义

如果我在代码中使用它就可以正常工作:

void * myvoid;

__asm
{
    push ecx;
    mov ecx, imageMousePressed;
    mov [myvoid], ecx;
    pop ecx;
}

我知道这不是一个很好的解决方案,但无论如何有人可以帮助它工作吗?

【问题讨论】:

  • 你能详细说明你为什么要这样做吗? void*(void 指针)在没有任何汇编程序的情况下是可能的。
  • 由于程序集分号,它不起作用。也许您应该尝试将其重写为模板函数。

标签: c++ assembly macros


【解决方案1】:

为什么不使用标准的 union hack?

template<class T>
void* as_void(T const & x)
{
   union hlp_t{
      void * v_ptr;
      T t;
   };
   hlp_t a;
   a.t = x;
   return a.v_ptr;
}

用法:as_void(&amp;std::vector&lt;int&gt;::size)

【讨论】:

  • 呃,你确定联合中应该是T,而不是T*
  • @QPaysTaxes 是的,在我的例子中是 T -> void (std::vector::*)(int),所以 T 正是需要转换的,而 T* 会产生指针指针
【解决方案2】:

你不能给出这样的宏定义:

#define toVoidStar(xx,yy)\
    __asm push ecx; \
    __asm mov ecx, yy; \ 
    __asm mov [xx], ecx; \ 
    __asm pop ecx;

因为__asm push ecx; 之后的所有行都将被注释掉,因为使用了;。请参阅我对此question 的回答。

【讨论】:

  • 谢谢。有什么办法让它工作吗?在这种情况下内联函数不好,因为我不知道xx的类型。
  • 你只是想移动4个字节到myvoid中的地址指向的位置,对吧?
  • 是的,但我不能做 void * myvoid = &eventHandlerFunct 因为它是一个成员函数。无论如何,工会黑客的另一个答案工作正常,但我仍然好奇我的解决方案是否可以以某种方式工作。
  • 那么,如果您想尝试自己的解决方案,为什么不能将其设为inline 函数!
  • 模板 inline void* as_void2(T const x) { void * myVoid; __asm { 推送 ecx;移动 ecx, x; mov myVoid, ecx;流行音乐; } 返回 &myVoid; }
【解决方案3】:

因为__asm关键字是语句分隔符,所以也可以将汇编指令放在同一行(see this link):

__asm mov al, 2   __asm mov dx, 0xD007   __asm out dx, al

所以解决方案是省略分号,编译器会知道语句在哪里结束。

【讨论】:

  • 为了澄清自己,您只需删除宏中每个“行”末尾的分号吗?
  • @QPaysTaxes 是的。
猜你喜欢
  • 1970-01-01
  • 2016-04-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-15
  • 1970-01-01
  • 2021-08-12
  • 1970-01-01
相关资源
最近更新 更多