简体   繁体   English

在Mac OSX上编译NASM

[英]Compiling NASM on Mac OSX

Writing a compiler in school, last milestone is generating assembly code. 在学校编写编译器,最后一个里程碑是生成汇编代码。 Trying to learn NASM. 试图学习NASM。 Starting at the beginning, http://www.cs.lmu.edu/~ray/notes/nasmexamples/ , trying to compile a Hello World. 从头开始, 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

To assemble, link and run this program under Windows: 要在Windows下组装,链接和运行此程序:

nasm -fwin32 helloworld.asm
gcc helloworld.obj
a

Under Linux, you'll need to remove the leading underscores from function names, and execute 在Linux下,您需要从函数名中删除前导下划线,然后执行

nasm -felf helloworld.asm
gcc helloworld.o
./a.out

But I'm on OSX. 但我在OSX上。 Found this little resource: http://salahuddin66.blogspot.com/2009/08/nasm-in-mac-os-x.html . 找到这个小资源: http//salahuddin66.blogspot.com/2009/08/nasm-in-mac-os-x.html In Mac OS X we should use format macho... 在Mac OS X中我们应该使用格式化的...

nasm -f macho -o hello.o hello.asm

...and for the linker (we need to specify the entry point)... ...以及链接器(我们需要指定入口点)...

ld -e main -o hello hello.o

But when I do this... 但是当我这样做的时候......

Undefined symbols:
    "printf", referenced from:
        _main in hello.o
ld: symbol(s) not found for inferred architecture i386

Sorry, I know it's a lot to read. 对不起,我知道这很重要。 And I doubt there are many NASM coders around these parts, but worth a try right? 我怀疑这些部件周围有很多NASM编码器,但值得一试吗? I'd appreciate any help I can get. 我很感激我能得到任何帮助。

Function printf is defined in some C library (on Linux, that would be in eg /lib/libc.so.6 or /lib/x86_64-linux-gnu/libc.so.6 ) so you need to link to that library (I don't know what it is on MacOSX) 函数printf在某些C库中定义(在Linux上,例如/lib/libc.so.6/lib/x86_64-linux-gnu/libc.so.6 ),因此您需要链接到该库(我不知道它在MacOSX上是什么)

You could do directly system calls ie syscalls (I don't know the details for MacOSX, and I don't know if they are publicly available). 您可以直接进行系统调用,系统调用 (我不知道MacOSX的详细信息,我不知道它们是否公开可用)。 On Linux, the Linux Assembly Howto give the details. 在Linux上, Linux程序集如何提供详细信息。 You need to find equivalent details for your operating system. 您需要找到适用于您的操作系统的详细信息。

(BTW, using entirely free software is definitely easier for such tasks, because their specification and source code is available; with proprietary software like probably MacOSX is, you need to get the from the software provider, sometimes it is very very expensive) (顺便说一句,使用完全免费的软件对于此类任务来说肯定更容易,因为他们的规范和源代码是可用的;使用像MacOSX这样的专有软件,你需要从软件提供商那里获得,有时它非常昂贵)

The program in your example is a 32-bit Windows program. 您的示例中的程序是32位Windows程序。 These days, it's probably better to write a 64-bit program. 现在,编写64位程序可能更好。

To covert this to 64-bit macOS program, you should make sure you have a recent version of nasm, and have gcc installed. 要将其转换为64位macOS程序,您应确保拥有最新版本的nasm,并安装了gcc。

The program should now look like this: 该程序现在应该如下所示:

; ----------------------------------------------------------------------------------------
; 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

You'll note a few differences: 你会注意到一些差异:

  • In 64 bit land, the first parameter is in RDI, not on the stack 在64位域中,第一个参数在RDI中,而不在堆栈中
  • The stack must be aligned on a 16-byte boundary before calling. 在调用之前,堆栈必须在16字节边界上对齐。 When main is entered, the operating system has placed the (8 byte) return address of main on the stack, so pushing rbx before calling puts serves to get the stack realigned. 当进入main时,操作系统已将main的(8字节)返回地址放在堆栈上,因此在调用puts之前按下rbx puts堆栈重新排列。
  • Also, nasm on macOS needs rel . 另外,macOS上的nasm需要rel

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM