Assembly 如何在MacOSX上使用nasm进行编译

Assembly 如何在MacOSX上使用nasm进行编译,assembly,nasm,Assembly,Nasm,我正试图在汇编程序上编译和链接我的第一个程序。 我尝试编译以下代码: ; %include "stud_io.inc" global _main section .text _main: xor eax, eax again: ; PRINT "Hello" ; PUTCHAR 10 inc eax cmp eax, 5 jl again 在用于编译和链接程序的console命令下方: -bash-3.2$ nas

我正试图在汇编程序上编译和链接我的第一个程序。 我尝试编译以下代码:

; %include "stud_io.inc"    
global _main     

section .text
_main: 
    xor eax, eax
again:
    ; PRINT "Hello"
    ; PUTCHAR 10
    inc eax     
    cmp eax, 5
    jl again
在用于编译和链接程序的console命令下方:

-bash-3.2$ nasm -f macho main.asm -o main.o  && ld -e _main -macosx_version_min 10.8 -arch x86_64 main.o
但结果是:

ld: warning: ignoring file main.o, file was built for i386 which is not the architecture being linked (x86_64): main.o
Undefined symbols for architecture x86_64:
  "_main", referenced from:
     -u command line option
ld: symbol(s) not found for architecture x86_64
我认为有必要为x86_64编译main.asm文件。。
如何正确地为我的系统编译程序

我建议首先更新您的

之后,尝试运行以下命令:

nasm -f macho64 main.asm -o main.o  && ld -e _main -macosx_version_min 10.8 -arch x86_64 main.o -lSystem
请注意,新命令在上面添加了JasonD的建议(
macho64
),但也在
ld
命令中添加了
-lSystem
,以阻止ld抛出以下错误:

ld: dynamic main executables must link with libSystem.dylib for architecture x86_64

我注意到大多数示例都显示了独立的汇编程序,但从C调用汇编可能更常见。我创建了一个简单的C程序,它使用最小的nasm汇编函数,如下所示:

extern unsigned cpuid(unsigned n);

/* ... */
        unsigned n = cpuid(1);
section .text
    global _cpuid

_cpuid:
    push rbp
    mov rbp, rsp
    mov rax, rdi
    cpuid
    mov rax, rcx
    leave
    ret
程序集如下所示:

extern unsigned cpuid(unsigned n);

/* ... */
        unsigned n = cpuid(1);
section .text
    global _cpuid

_cpuid:
    push rbp
    mov rbp, rsp
    mov rax, rdi
    cpuid
    mov rax, rcx
    leave
    ret
您可以在此处看到整个过程,包括makefile中的nasm CLI选项:

它通过打印出一些CPU特定功能的可用性来做一些稍微有用的事情。(但它是通过使用CPUID实现的,而不检查它是否可用。不过,如果CPU是英特尔的,并且比i486更新,那也没关系。)


该示例使用ports集合中的nasm在Mac OS X Snow Leopard上进行了测试。删除下划线前缀是移植到Linux x86_64所需的唯一更改。

可以尝试静态链接吗

ld-macosx\u version\u min 10.13-e\u main-static main.o

nasm不识别此选项您运行的是哪一版本的nasm?-bash-3.2$nasm-v nasm版本0.98.40(Apple Computer,Inc.build 11)于2012年8月4日编译该版本的nasm非常过时。看看segfault,这是代码执行的一个问题。在
jl
指令之后,添加
ret
指令(因为您使用的是main)。请注意,如果您使用的是纯x86程序集,则需要使用
int0x80
中的exit系统调用退出(但在本例中不是这样)。请记住,PC计数器需要知道代码完成后继续执行的位置。
ld-lSystem my.o-e\u main-macosx\u version\u min 10.14-o exit
Result->
无法执行二进制文件
此外,在使用
-fmacho64
之前,我确实需要更新NASM,正如这里的其他注释所述。