在Mac上使用x86汇编语言

70

有没有人知道在Mac上写汇编语言的好工具(我正在寻找IDE),因为Xcode对我来说有点繁琐。

另外,在Intel Mac上,我能否使用通用的x86汇编语言?还是有修改过的指令集?有任何关于后Intel的信息吗?

还有:我知道在Windows上,汇编语言可以在由操作系统创建的模拟环境中运行,让代码认为它在运行自己专用的机器。OS X是否提供相同的功能?

7个回答

85
安装任何版本的面向Intel Mac的Xcode后,您应该可以编写汇编代码。 Xcode是一套工具,其中只有一个是IDE,所以如果您不想使用它,可以不使用。 (话虽如此,如果您发现有特定的问题,请在Apple的错误报告者上提交错误-每个错误都会发送到工程部门。)此外,安装Xcode将安装Netwide Assembler(NASM)和GNU Assembler(GAS);这将让您使用您最熟悉的汇编语法。
您还需要查看编译器和调试指南,因为这些文档记录了Mac OS X运行的各种架构使用的调用约定,以及二进制格式和加载程序的工作方式。特别是IA-32(x86-32)调用约定可能与您习惯的略有不同。
另一个要记住的事情是,Mac OS X上的系统调用接口与您可能在DOS / Windows,Linux或其他BSD版本上使用的不同。系统调用在Mac OS X上不被视为稳定的API;相反,您总是通过libSystem进行。这将确保您编写的代码可移植到操作系统的下一个版本。

最后,请记住,Mac OS X可以运行在各种硬件上 - 从32位Core Single到高端四核Xeon。通过汇编编码,您可能没有像您想象的那样进行优化;在一台机器上最优的东西,在另一台机器上可能是最劣的。苹果公司定期测量其编译器,并使用“-Os”优化标志调整其输出,使其在线路上表现良好,并且有广泛的矢量/矩阵处理库,您可以使用手动调整的CPU特定实现来获得高性能。

为了好玩而使用汇编很棒。但是出于速度考虑去使用汇编对于现在的人来说并不容易。


有两个人点赞了他的评论,但没有人真正修复了链接...如果苹果公司能够将旧链接重定向到新文章就好了...我发现从SO链接到苹果文档的链接几乎总是失效的... - ArtOfWarfare
3
存档网站版本(被切割前的最新版本):http://web.archive.org/web/20090622125037/http://developer.apple.com/documentation/DeveloperTools/CompilersDebuggers-date.html本文是有关苹果开发工具中编译器和调试器的文档,存档时间为2009年。 - Zimm3r

30

如前所述,请勿使用syscall。您可以使用标准的C库调用,但请注意栈必须按照苹果的IA32函数调用ABI进行16字节对齐。

如果您没有对齐栈,当您调用任何库或框架中的函数时,您的程序将在__dyld_misaligned_stack_error中崩溃。

以下代码片段在我的系统上汇编并运行:

; File: hello.asm
; Build: nasm -f macho hello.asm && gcc -o hello hello.o

SECTION .rodata
hello.msg db 'Hello, World!',0x0a,0x00

SECTION .text

extern _printf ; could also use _puts...
GLOBAL _main

; aligns esp to 16 bytes in preparation for calling a C library function
; arg is number of bytes to pad for function arguments, this should be a multiple of 16
; unless you are using push/pop to load args
%macro clib_prolog 1
    mov ebx, esp        ; remember current esp
    and esp, 0xFFFFFFF0 ; align to next 16 byte boundary (could be zero offset!)
    sub esp, 12         ; skip ahead 12 so we can store original esp
    push ebx            ; store esp (16 bytes aligned again)
    sub esp, %1         ; pad for arguments (make conditional?)
%endmacro

; arg must match most recent call to clib_prolog
%macro clib_epilog 1
    add esp, %1         ; remove arg padding
    pop ebx             ; get original esp
    mov esp, ebx        ; restore
%endmacro

_main:
    ; set up stack frame
    push ebp
    mov ebp, esp
    push ebx

    clib_prolog 16
    mov dword [esp], hello.msg
    call _printf
    ; can make more clib calls here...
    clib_epilog 16

    ; tear down stack frame
    pop ebx
    mov esp, ebp
    pop ebp
    mov eax, 0          ; set return code
    ret

有人能告诉我为什么使用“nasm -f macho hello.asm && gcc -arch i386 -e _main -lSystem -o hello hello.o && ./hello”运行此示例会在输出的末尾出现“总线错误: 10”吗? - Colin
搞定了:我认为有一个错误。clib_prolog的结尾应该减去%1字节以填充参数,而clib_epilog应该添加%1字节。我编辑了答案以反映这一点。 - Colin

10

最近我想学习如何在Mac OS X上编译Intel x86:

nasm的编译方法:

-o hello.tmp - outfile
-f macho - specify format
Linux - elf or elf64
Mac OSX - macho

对于ld:

-arch i386 - specify architecture (32 bit assembly)
-macosx_version_min 10.6 (Mac OSX - complains about default specification)
-no_pie (Mac OSX - removes ld warning)
-e main - specify main symbol name (Mac OSX - default is start)
-o hello.o - outfile

适用于Shell:

./hello.o - execution

一句话概括:

nasm -o hello.tmp -f macho hello.s && ld -arch i386 -macosx_version_min 10.6 -no_pie -e _main -o hello.o hello.tmp && ./hello.o

如果这对你有帮助,请告诉我!

我在这里的博客上写了如何做:

http://blog.burrowsapps.com/2013/07/how-to-compile-helloworld-in-intel-x86.html

需要更详细的解释,我在我的Github上解释了:

https://github.com/jaredsburrows/Assembly


7
在Mac上运行汇编代码只需要3个步骤。可以使用XCODE完成,但最好使用NASM命令行工具。
为了方便起见,我已经安装了Xcode,如果您已经安装了Xcode,那就太好了。
但是您也可以不使用XCode。
只需按照以下步骤操作:
1.首先使用Homebrew安装NASM:`brew install nasm`
2.使用以下命令将.asm文件转换为Obj文件:`nasm -f macho64 myFile.asm`
3.使用以下命令运行Obj文件以查看输出:`ld -macosx_version_min 10.7.0 -lSystem -o OutPutFile myFile.o && ./64`
下面是一个简单的文本文件,文件名为myFile.asm,供您参考。
global start
section .text

start:
    mov     rax, 0x2000004 ; write
    mov     rdi, 1 ; stdout
    mov     rsi, msg
    mov     rdx, msg.len
    syscall

    mov     rax, 0x2000001 ; exit
    mov     rdi, 0
    syscall

section .data

msg:    db      "Assalam O Alaikum Dear", 10
.len:   equ     $ - msg

我已经在MacOS上下载了DosBox,并感觉这是在MacOS上运行汇编语言的最佳方式。 让我分享一些步骤。 1- 下载MAC的DosBox.dmg并安装 2- 将名为Assembly的文件夹复制到计算机上的任何位置,在我的情况下,我将assembly文件夹复制到桌面。(我从一个网站下载了这个文件夹,让我在新线程中分享一个git链接以进行下载) 3- 在DosBOX中运行命令“mount c:/users/akhzar/desktop/Assembly”,然后写入c:并按Enter键。 4- 现在您在C驱动器中可以运行汇编语言命令。 - Akhzar Nazir
1- 现在使用以下命令运行.asm文件 c:> nasm a.asm -o a.com -l a.lst (这将创建两个文件,一个是.lst,另一个是.com)2- 现在运行AFD以查看调试模式 c:> afd a.com (使用f1、f2功能键运行程序直到终止)3- 要从调试器返回,请使用以下命令退出 - Akhzar Nazir
从以下链接下载汇编语言文件夹: https://github.com/akhzarna/AssemblyLanguageOnMac - Akhzar Nazir
如果我使用-macosx_version_min 10.14.1,则会出现以下错误:Undefined symbols for architecture x86_64: "_main", referenced from: implicit entry/start for main executablesymbol(s) not found for inferred architecture x86_64 - gabbler
@AkhzarNazir:原始问题有点模糊,不清楚指的是何种汇编代码开发。我认为原始问题是关于如何在Mac上本地开发汇编代码-使用Mac工具链并在Mac上执行最终结果。您展示了如何在Mac上运行的模拟运行时中为DOS / Windows开发汇编语言,这不是我认为原始问题所涉及的内容。 - Petr Lazecky

6

对于英特尔架构的 Mac,我能使用通用的 x86 汇编语言吗?还是必须使用修改过的指令集?如果有关于英特尔 Mac 后期汇编的信息也请提供。

实际上,它们使用的是相同的指令集和芯片。


1

可用的功能取决于您的处理器。苹果使用与其他人相同的英特尔芯片。因此,是的,通用的x86应该没问题(假设您不在PPC上:D)。

就工具而言,我认为您最好的选择是一个能够“理解”汇编语言的好文本编辑器。


0

别再为在Mac上寻找汇编语言的IDE而烦恼了。但是,记住Mac是UNIX系统。请参考http://asm.sourceforge.net/articles/linasm.html。这是一个不错的(虽然简短)指南,教你如何通过GCC在Linux上运行汇编语言。你可以仿照这个方法在Mac上操作。由于Mac使用Intel芯片,所以你需要关注Intel语法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接