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上编译它.
您收到总线错误的原因是您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)
值得注意的变化是:
ret内联组件ebp而不是esp引用参数doStuffflags为0x00100002更改(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的基本信息/链接,