【问题标题】:Xcode: running ASMXcode:运行 ASM
【发布时间】:2014-01-09 20:54:51
【问题描述】:

我有这个 ASM,我一直试图在 Xcode 中运行但没有成功:

_asm
{
    push eax
    push ebx
    push ecx
    mov eax,[A]
    mov ebx,[B]
    xor eax,ebx
    mov ecx,eax
    xor ecx,ebx
    mov ebx,ecx
    xor eax,ebx
    mov [A],eax 
    mov [B],ebx 
    pop eax 
    pop ebx 
    pop ecx 
}

我已尝试将其更改为__asm__,但错误仍然存​​在:

inline asm:6:2: 未知使用没有大小后缀的指令助记符

我在网上搜索了几个小时,但似乎没有人回答我的问题。

我正在运行 Xcode 5.0.2。

有谁知道我可能需要在 Xcode 中设置什么才能运行它?

【问题讨论】:

  • 听起来编译器期待gas 语法(其中每条指令都有一个显示其大小的后缀,寄存器名称以% 开头,源操作数和目标操作数颠倒了)。它看起来像 pushl %eax movl (A), %eax 等等,或者非常接近的东西。
  • 你可以说 -Xassembler -msyntax=intel 让它识别你拥有的东西。
  • 它需要的远不止这些。请参阅en.wikibooks.org/wiki/X86_Assembly/GAS_Syntax 了解更多信息。
  • 在为 x86 编写汇编程序时,有两种常见的格式:intel 格式和 att 格式。这些格式之间存在许多差异(例如 Unheilig 提到的 %)。根据您的汇编程序,您可以要求它使用一种格式或另一种格式。您发布的代码看起来像英特尔格式。错误消息清楚地表明它正在为 att 格式编译。您要么需要告诉编译器使用 intel 格式(正如 cHao 试图建议的那样),要么以 att 格式重新编写代码。两种格式都有很多参考资料(请查看 google)。

标签: xcode assembly


【解决方案1】:

等效的 GCC 样式 asm 语句是:

__asm__(
    "push %%eax\n\t"
    "push %%ebx\n\t"
    "push %%ecx\n\t"
    "mov %0,%%eax\n\t"
    "mov %1,%%ebx\n\t"
    "xor %%ebx,%%eax\n\t"
    "mov %%eax,%%ecx\n\t"
    "xor %%ebx,%%ecx\n\t"
    "mov %%ecx,%%ebx\n\t"
    "xor %%ebx,%%eax\n\t"
    "mov %%eax,%0\n\t"
    "mov %%ebx,%0\n\t"
    "pop %%ecx\n\t"
    "pop %%ebx\n\t"
    "pop %%eax"
    : "+m" (A), "+m" (B));

(我通过将堆栈上保存的值弹出回其原始寄存器来纠正了一个明显的错误。)

我不确定这个汇编语句的意义是什么。用三行 C/C++ 代码可以更有效地完成一些事情需要付出很多努力:

temp = A;
A = B;
B = temp;

如果我要假装它做了一些有用的事情,而不仅仅是交换两个变量,那么我建议去掉明显不重要的 PUSH/POP 指令,如下所示:

__asm__(
    "xor %1,%0\n\t"
    "mov %0,%2\n\t"
    "xor %1,%2\n\t"
    "mov %2,%1\n\t"
    "xor %1,%0"
    : "+r" (A), "+r" (B), "=r" (temp));

【讨论】:

  • 如果目标是交换两个值,那么 asm ("" : "=r" (b), "=r" (a) : "0" (a), "1" (b)); 怎么样?难以击败 0 项性能声明...
  • 好吧,如果原始发布者的代码应该是一个实际示例,我的建议是使用我提供的 C/C++ 示例代码。
  • 没错,这可能是最好的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多