Mac上的x86组装

时间:2020-03-05 18:38:32  来源:igfitidea点击:

有谁知道在Mac上编写汇编的任何好工具(我正在寻找IDE)。 Xcode对我来说有点麻烦。

另外,在Intel Mac上,我可以使用通用x86 asm吗?还是有修改后的指令集?有关后英特尔的任何信息。

另外:我知道在Windows上,asm可以在OS创建的模拟环境中运行,以使代码认为它在自己的专用计算机上运行。 OS X是否提供相同的功能?

解决方案

回答

Also, on the Intel Macs, can I use generic x86 asm? or is there a modified instruction set? Any information about post Intel Mac assembly helps.

这是相同的指令集;这是相同的筹码。

回答

可用的功能取决于处理器。苹果使用与其他所有人相同的英特尔产品。所以是的,通用x86应该没问题(假设我们不在PPC:D上)。

就工具而言,我认为最好的选择是"理解"汇编的优秀文本编辑器。

回答

忘了寻找在Mac上编写/运行/编译汇编器的IDE。但是,请记住,mac是UNIX。参见http://asm.sourceforge.net/articles/linasm.html。一个在Linux上通过GCC运行汇编程序的不错的指南(虽然简短)。我们可以模仿这个。 Mac使用Intel芯片,因此我们需要查看Intel语法。

回答

在安装了针对基于Intel的Mac的任何版本的Xcode之后,我们应该能够编写汇编代码。 Xcode是一套工具,其中只有一个是IDE,因此,如果我们不想使用它,则不必使用它。 (也就是说,如果我们发现有些笨拙的东西,请把每个错误提交给Apple的错误报告者。)此外,安装Xcode会同时安装Netwide汇编器(NASM)和GNU汇编器(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的各种硬件上。通过汇编语言编码,我们可能没有想到的那样优化。一台机器上的最佳选择可能对另一台机器来说是最理想的。 Apple会定期测量其编译器,并使用" -Os"优化标志对其输出进行调整,以使其在整个生产线上都不错。此外,我们还可以使用大量的矢量/矩阵处理库,通过手动调整的CPU特定实现来获得高性能。 。

去组装很有趣。如今,为了速度而去组装并不适合胆小的人。

回答

如前所述,请勿使用syscall。虽然我们可以使用标准的C库调用,但是请注意,每个Apple的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