在学校编写编译器,最后一个里程碑是生成汇编代码。试图学习NASM。从头开始,http://www.cs.lmu.edu/~ray/notes/nasmexamples/,尝试编译Hello World。
; ----------------------------------------------------------------------------
; helloworld.asm
;
; This is a Win32 console program that writes "Hello, World" on one line and
; then exits. It needs to be linked with a C library.
; ----------------------------------------------------------------------------
global _main
extern _printf
section .text
_main:
push message
call _printf
add esp, 4
ret
message:
db 'Hello, World', 10, 0
在Windows下组装,链接和运行此程序:
nasm -fwin32 helloworld.asm
gcc helloworld.obj
a
在Linux下,您需要从函数名中删除前导下划线,然后执行
nasm -felf helloworld.asm
gcc helloworld.o
./a.out
但我在OSX上。找到这个小资源:http://salahuddin66.blogspot.com/2009/08/nasm-in-mac-os-x.html。在Mac OS X中,我们应该使用格式化...
nasm -f macho -o hello.o hello.asm
...和链接器(我们需要指定入口点)......
ld -e main -o hello hello.o
但是当我这样做的时候......
Undefined symbols:
"printf", referenced from:
_main in hello.o
ld: symbol(s) not found for inferred architecture i386
对不起,我知道这很重要。我怀疑这些部件周围有很多NASM编码器,但值得一试吗?我很感激能得到的任何帮助。
答案 0 :(得分:3)
函数printf
在某些C库中定义(在Linux上,例如/lib/libc.so.6
或/lib/x86_64-linux-gnu/libc.so.6
),因此您需要链接到该库(我不知道)它在MacOSX上是什么
您可以直接system calls,即syscalls(我不知道MacOSX的详细信息,我不知道它们是否公开发布)。在Linux上,Linux Assembly Howto提供了详细信息。您需要找到适用于您的操作系统的详细信息。
(BTW,使用完全免费的软件对于此类任务来说肯定更容易,因为它们的规格和源代码是可用的;使用像MacOSX这样的专有软件,你需要从软件提供商那里获得,有时它非常昂贵)
答案 1 :(得分:2)
您的示例中的程序是32位Windows程序。现在,编写64位程序可能会更好。
要将其转换为64位macOS程序,您应确保拥有最新版本的nasm,并安装了gcc。
该程序现在应如下所示:
; ----------------------------------------------------------------------------------------
; This is an macOS console program that writes "Hola, mundo" on one line and then exits.
; It uses puts from the C library. To assemble and run:
;
; nasm -fmacho64 hola.asm && gcc hola.o && ./a.out
; ----------------------------------------------------------------------------------------
global _main
extern _puts
section .text
_main: push rbx ; Call stack must be aligned
lea rdi, [rel message] ; First argument is address of message
call _puts ; puts(message)
pop rbx ; Fix up stack before returning
ret
section .data
message: db "Hola, mundo", 0 ; C strings need a zero byte at the end
你会注意到一些不同之处:
rbx
之前按puts
会使堆栈重新排列。rel
。