0

As part of a class, I need to write assembly code with specific format. The teacher refers to it as "Intel syntax x86-64". I tried to compile it with the given command (gcc -O3 -o op sc.s) and despite working great on a linux PC it fails on a Mac. After some researches I found Mac OS doesn't support this syntax and following the advices from the teacher I tried to run Linux from a bootable USB key and on a Virtual Machine (using VirtualBox) but both fail due to keyboard compatibility issues. I searched a few online solution but none of them could compile the source code without problem. How can I run it without buying a new computer ? I would like to run this exact syntax if it's possible.
Thank you for reading me !

Here a exemple of code he gave us :

        .intel_syntax noprefix
        .data
msg:    .asciz "Hello, world!\n"
        .text
        .global main
        .type main, @function
main:   PUSH RBP
        MOV RBP, RSP
        MOV RDI, offset flat:msg
        CALL printf
        MOV EAX, 0
        POP RBP
        RET 

With can be compiled with gcc (shown in live) yet compiling it with gcc -o hw1 hw.s or gcc -o hw1 -masm=intel hw.s give me the following error :

hw.s:6:9: error: unknown directive
        .type main, @function
        ^
hw.s:9:29: error: unknown token in expression
        MOV RDI, offset flat:msg

Edit: Setting up an ssh server on the VM and connecting to the VM via the host terminal made things much easier with VirtualBox, see https://stackoverflow.com/a/10532299/5770818

Maxime A
  • 90
  • 1
  • 9
  • macOS uses a different assembler that does not support this syntax. You can install the GNU assembler gas to get this to work. But even then there are other differences (such as symbol decoration) you have to take care of. – fuz May 05 '18 at 16:47
  • as a side note, "keyboard compatibility issues" isn't relevant. Any OSes can be installed on any keyboard layouts – phuclv May 05 '18 at 16:55
  • @PaulR I tried to install nasm with homebrew, however I receive other errors letting me think there may be some syntax differences between the expected syntax and the one my file is written in. – Maxime A May 05 '18 at 17:04
  • @fuz isn't GNU part of gcc ? And isn't there a way to compile this exact syntax ? – Maxime A May 05 '18 at 17:05
  • @LưuVĩnhPhúc I used a MacOS-Belgian keyboard which is not well recognized by linux, therefore some essential character are impossible to write in a VM (even with visual keyboard) and a bootable installation doesn't recognize the keyboard or trackpad. I wrote that to suggest classic boot or emulation didn't work well. – Maxime A May 05 '18 at 17:07
  • GNU is a huge project, gcc is one part of it, gas another. gcc does not automatically come with gas. Assembly is assembled, not compiled. You can assemble your code with gas after installing it. – fuz May 05 '18 at 17:11
  • The `gcc` command on MacOS does not run gcc -- it runs clang instead. You can see this by typing `gcc -v` -- it will print out "Apple LLVM version"... – Chris Dodd May 05 '18 at 17:20
  • Thanks for the precision ! – Maxime A May 06 '18 at 06:44

2 Answers2

2

I don't think there's a good solution on macOS. As far as I know, GNU binutils don't support the Mach binary format on macOS, which means you can't just use the same assembler as on Linux (gas).

The issue isn't only the syntax, in fact, the syntax as such is partially supported. You will also run into other platform-related differences. For example, the ".type" directive wouldn't be used on macOS, and symbol names are prefixed with an underscore.

If you have keyboard issues with VMs, I'd recommend setting up some server Linux distribution in the VM and then run it in headless mode. Access it by logging in with ssh. This way you interact with it through Terminal, and shouldn't have keyboard problems.

Docker might also be an option, since it actually runs Linux in a VM on macOS, but might be more work to figure out.

Anyway, if you're interested in a version of the code that works on macOS:

        .intel_syntax noprefix
        .data
msg:    .asciz "Hello, world!\n"
        .text
        .global _main
_main:  PUSH RBP
        MOV RBP, RSP
        LEA RDI, [RIP + msg]
        CALL _printf
        MOV EAX, 0
        POP RBP
        RET 

I removed the ".type" line, added underscores to main and printf, and changed "MOV RDI, offset flat:msg" to "LEA RDI, [RIP + msg]".

Build with "clang -o hw1 hw1.s", no reason to pretend we're running gcc ;)

snowcat
  • 284
  • 1
  • 5
  • 1
    You can install the homebrew(or macports, build your own from scratch) version of GCC and binutils (which contains `as`) to generate macho64 executables. – Michael Petch May 05 '18 at 17:53
  • 1
    You are mistaken, homebrew binutils don't contain gas. If you build binutils from source, configure will tell you that it won't build gas. What you _can_ do is build binutils for ELF on macOS (configure --target=x86_64-apple-elf), but then your next job is writing a kernel extension that implements ELF loading. – snowcat May 05 '18 at 18:15
  • @snowcat Thank you very much ! I'll get more information for the ssh plan but it seems like a good option, I didn't know it was possible. – Maxime A May 06 '18 at 06:47
0

You're attempting to assemble a file using gas syntax, so you need to use an assembler that supports that -- either gas iteself, or something like yasm

Chris Dodd
  • 119,907
  • 13
  • 134
  • 226
  • or clang, which comes with MacOS. (It doesn't accept `.type` directives for MacOS targets, though. And MacOS uses leading-underscore decorators on symbol names, and doesn't allow 32-bit absolute addresses, but it's the same syntax.) – Peter Cordes Jun 11 '21 at 02:44