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,正如这里的其他注释所述。