总线错误:在Mac OS X上使用GCC进行内联x86组装

sty*_*fle 4 macos assembly gcc

当我尝试在Snow Leopard上运行使用gcc 4.2.1编译的代码时,我收到"总线错误"

#include <stdio.h>

/*__declspec(naked)*/ void
doStuff(unsigned long int val, unsigned long int flags, unsigned char *result)
{
    __asm{
        push eax
        push ebx
       push ecx
        push edx

        mov eax, dword ptr[esp + 24]//val
        mov ebx, dword ptr[esp + 28]//flags
        //mov ecx, dword ptr[esp + 32]//result

        and eax, ebx
        mov result, eax

        pop edx
        pop ecx
        pop ebx
        pop eax

        ret
    }
}

int main(int argc, char *argv[])
{
    unsigned long val = 0xAA00A1F2; 
    unsigned long flags = 0x00100001;   
    unsigned char result = 0x0;

    doStuff(val, flags, &result);   
    printf("Result is: %2Xh\n", result);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我正在使用以下命令进行编译,gcc -fasm-blocks -m32 -o so so.c没有任何错误或警告.我试图在doStuff()函数中运行一些汇编指令并将结果分配给答案.我究竟做错了什么?

注意:这在Windows上的Visual Studio中运行良好,但我不得不注释掉declspec(裸)以获取gcc在Mac上编译它.

Dea*_*sek 6

您收到总线错误的原因是您ret在汇编代码中调用. ret导致程序控制转移到堆栈顶部的返回地址,您可以通过使用push和来操作pop.我强烈建议查看ret英特尔指令集参考中的内容.

下面是我在运行Mac OS X 10.6.7的iMac上编译并成功运行的代码.

#include <stdio.h>

/*__declspec(naked)*/ void
doStuff(unsigned long int val, unsigned long int flags, unsigned char *result)
{
  __asm
    {
        push eax
        push ebx
        push ecx

        mov eax, dword ptr[ebp + 8]  //val
        mov ebx, dword ptr[ebp + 12] //flags
        mov ecx, dword ptr[ebp + 16] //result

        and eax, ebx
        mov [ecx], eax

        pop ecx
        pop ebx
        pop eax
      }
}

int main(int argc, char *argv[])
{
  unsigned long val =   0xAA00A1F2;
  unsigned long flags = 0x00100002;
  unsigned char result = 0x0;

  doStuff(val, flags, &result);
  printf("Result is: %2Xh\n", result);

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

值得注意的变化是:

  1. 拆除ret内联组件
  2. 使用寄存器ebp而不是esp引用参数doStuff
  3. 改变flags0x00100002

更改(1)修复了总线错误,(2)使参数更加一致,并且(3)只是确保函数按预期工作的快速方法.

最后,我强烈建议您熟悉GNU调试器GDB,如果您还没有.您可以在项目页面http://www.gnu.org/software/gdb/上找到有关它的更多信息,以及有关Mac实现和教程的信息,请访问http://developer.apple.com/library/mac/ #documentation/DeveloperTools/gdb/gdb/gdb_toc.html.

编辑:添加了GDB的基本信息/链接,