【问题标题】:Replacing function with inline assembly C用内联汇编 C 替换函数
【发布时间】:2014-07-24 22:49:13
【问题描述】:

我有一个函数,我想将其内部代码转换为程序集(出于各种原因):

int foo(int x, int y, int z);

我使用以下方法生成了汇编代码:

clang -S -mllvm --x86-asm-syntax=intel foo.c

程序集输出: foo.s 开始于:

_foo:                               ## @foo
    .cfi_startproc
## BB#0:
    push    RBP
Ltmp2:
    .cfi_def_cfa_offset 16
...

我假设这是该函数的相应汇编代码。我的问题是,我应该将汇编输出的哪一部分复制到 C 代码中(我正在尝试使用内联汇编),以便该函数可以工作?代码应如下所示:

int foo(int x, int y, int z) {
   __asm__("..."); // <-- What goes inside?
}

谢谢

【问题讨论】:

  • 您可以让您的调试器在汇编代码上运行,然后您可以踩到该函数并找出实际需要使用的部分。但请记住,编译器优化了很多东西,所以它可能并不总是正确的。
  • 嗯,所以如果我找到函数实际开始的位置,将汇编代码直接复制并粘贴到 C 中(用 asm 等包裹)行得通吗?我不需要指定操作数列表或clobber 列表或其他任何东西,对吗?
  • 除非你的 asm 很小并且你认为它应该被内联,否则将你的整个函数写在一个 asm 源文件中,然后调用它。 (当然,在 C 头文件中保留它的原型。)然后您的构建系统必须知道为 x86 和/或 x86-64 构建编译该 asm 源,而不仅仅是在 C 中使用 #ifdef。获得内联 asm正确的,尤其是。让约束、破坏和输入/输出完全正确是很困难的,但需要它才能正常工作。 (如果您确实走那条路,请检查反汇编输出以确保您的 ASM 以您期望的方式开槽)。

标签: c assembly clang inline-assembly


【解决方案1】:

您必须查看该函数的反汇编并编写__asm__。例如下面的代码

int foo(int x, int y, int z) {
x = y+z; return x; }

将产生以下内容的反汇编:

int foo(int x, int y, int z) {
  push        ebp  
  mov         ebp,esp 
  sub         esp,0C0h 
  push        ebx  
  push        esi  
  push        edi  
  lea         edi,[ebp-0C0h] 
  mov         ecx,30h 
  mov         eax,0CCCCCCCCh 
  rep stos    dword ptr es:[edi] 

  x = y+z;
  mov         eax,dword ptr [y] 
  add         eax,dword ptr [z] 
  mov         dword ptr [x],eax 

  return x;
  mov         eax,dword ptr [x] 
}

所以你必须在下面添加声明x= y+z

 mov         eax,dword ptr [y] 
 add         eax,dword ptr [z] 
 mov         dword ptr [x],eax 

【讨论】:

  • 好的,我有一个小问题,编译器抱怨我没有返回变量(因为我是通过程序集返回的),有什么办法解决这个问题?
  • 包括 mov eax,dword ptr [x] ,它有效。 int foo(int x, int y, int z) { x = y+z; _asm{ mov eax,dword ptr [x] } }
  • 您是否使用 MSVC 进行编译?你知道用 clang 做同样的事情吗?
  • 是的。我以前从未使用过的 Clang。但是,基于 Clang 的 C++ 编译器允许内联汇编,但有以下注意事项:您不能将汇编与 C++ 代码混合使用。不要触摸堆栈指针 (RSP)。汇编器必须使用 AT&T 的逐行语法,而不是更熟悉的 Intel 块语法。有关更多信息,请参阅 GCC-Inline-Assembly-HOWTO。基于 Clang 的 C++ 编译器以不同于 BCC32 支持的内联汇编的方式支持内联汇编:基于 Clang 的 C++ 编译器支持的汇编语法是逐行 AT&T 语法,而不是更熟悉的 Intel 块语法。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多