Running x86_64 ASM with NASM on Your Mac
Introduction
The assembly in this class is written for x86_64 processors. Macs with an M-series chip (M1, M2, etc.) use an ARM processor, so x86_64 programs will not run on them natively. To get around this, we will use UTM to emulate an x86_64 computer, and run a bare-bones Ubuntu Server inside it. You will then connect to it from VS Code over SSH, so you can write and run your assembly from the editor on your Mac.
Because UTM is pretending to be a different type of processor, everything inside the VM runs noticeably slower than normal (the install and first boot especially). This is expected. Your assembly programs are tiny, so once everything is set up you should barely notice.
If you have an Intel Mac or a Windows machine, you can skip this guide and follow the normal VM install, then install NASM.
Prerequisites
- An M-series Mac running macOS
- About 30 GB of free disk space
- VS Code installed on your Mac
Part 1: Install UTM
Download UTM from https://mac.getutm.app and drag it into your Applications folder. (The App Store version costs money but is the same software. The free download from the website is fine.)
If you use Homebrew, you can instead run:
brew install --cask utmPart 2: Download Ubuntu Server (x86_64)
Download the main Ubuntu Server LTS option (the big download button at the top of the page). This is the amd64 (x86_64) version, which is what we want.
Do not choose the ARM option. The page also lists an “Ubuntu Server for ARM” download further down. Skip it.
When the download finishes, check the file name in your Downloads folder. It should look like
ubuntu-24.04.x-live-server-amd64.iso. If the name containsarm64instead ofamd64, delete it and download the correct one.
amd64 is the name for 64-bit x86 (it works for both Intel and AMD). An arm64 image would give you a VM that cannot assemble x86_64 code with NASM, even though it would install and run without errors.
Part 3: Create the Virtual Machine
Open UTM and click Create a New Virtual Machine.
Choose Emulate (not Virtualize).
Choose Linux.
Under Boot ISO Image, click Browse and select the Ubuntu Server ISO you just downloaded. Click Continue.
On the hardware screen, set the following.
- Architecture:
x86_64 - System:
Standard PC (Q35 ICH9, 2009)(the default) - Memory:
2048MB (or4096if your Mac has 16 GB or more) - CPU Cores:
2to4
Click Continue.
- Architecture:
Set the storage to 24 GB (or more). Click Continue.
Skip the shared directory step by clicking Continue.
Name the VM something like
csc222-x86and click Save.
Part 4: Install Ubuntu Server
Select your VM in the UTM sidebar and click the Play button. A window with a console will appear. Wait for the installer to load (this can take a few minutes).
Click inside the window and use the keyboard to go through the installer. Use the arrow keys to move,
Enterto select, andSpaceto check or uncheck boxes.Screen What to choose Language English Installer update Continue without updatingKeyboard Your layout (probably the default) Type of install Ubuntu Server (minimized) is fine. The regular Ubuntu Server works too. Network Leave the defaults (DHCP) Proxy / mirror Leave the defaults Storage Use an entire disk (the defaults) Profile setup Pick a name, server name, username, and password. Remember the username and password. You will need them to log in. Ubuntu Pro Skip for nowSSH Check Install OpenSSH server. This is required for VS Code to connect. Do not import any SSH identity.Featured snaps Select nothing
Notice that we never choose a desktop environment. Ubuntu Server only gives you a terminal, which is all we need.
The install will now run. This is the slowest step and can take 20 to 40 minutes under emulation. Wait until the top of the screen says Install complete! and the Reboot Now option appears.
Before you reboot, remove the install disc so it does not boot the installer again.
- In the UTM window toolbar (or the VM’s settings), find the CD/DVD drive entry and choose Clear (sometimes labeled Eject).
Select Reboot Now. If you see a message about removing the installation medium, just press
Enter.After it boots (it may take a minute or two), you will see a
login:prompt. Log in with the username and password you created.
Part 5: Find the VM’s IP Address
In the VM’s console, run the following command.
ip -4 addr showLook for an address like 192.168.64.x under the main network interface (it is probably named enp0s1 or similar). Ignore 127.0.0.1, since that is the VM talking to itself. In the rest of this guide we will pretend the address is 192.168.64.5. Use your own.
Open the VM’s settings in UTM, go to Network, and make sure the Network Mode is Shared Network. Then restart the VM.
Part 6: Connect from the Mac Terminal
Before using VS Code, check that SSH works. In a terminal on your Mac (not in the UTM window), run the following. Replace josh with your VM username and the IP with your own.
The first time, it will ask Are you sure you want to continue connecting? Type yes and press Enter, then enter your VM password. If you land at a prompt on the VM, SSH is working. Type exit to come back to your Mac.
Run the following on your Mac to create a key (press Enter through the prompts if you don’t already have one), and copy it to the VM. You will not have to type your password each time you connect.
ssh-keygen -t ed25519
ssh-copy-id [email protected]Part 7: Connect with VS Code
Open VS Code on your Mac and open the Extensions panel (
Cmd+Shift+X).Search for Remote - SSH (published by Microsoft) and install it.
Open the Command Palette with
Cmd+Shift+Pand run Remote-SSH: Open SSH Configuration File…. Choose the one inside your home folder (~/.ssh/config).Add an entry for your VM, using your own username and IP.
Host csc222-x86 HostName 192.168.64.5 User joshOpen the Command Palette again and run Remote-SSH: Connect to Host…, then choose
csc222-x86.A new VS Code window will open. Select Linux if asked about the platform, and enter your password if asked. The first connection downloads and installs VS Code’s helper (the VS Code Server) onto the VM. Under emulation this can take a few minutes.
When it finishes, the bottom left corner of the window will show
SSH: csc222-x86. Use File → Open Folder… to open a folder on the VM (such as your home folder), and open a terminal inside VS Code withCtrl+`. That terminal is running on the VM.
If VS Code can’t connect later, the VM may have been given a different IP address. Log in at the UTM console, run ip -4 addr show again, and update HostName in your ~/.ssh/config. The VM must be running in UTM for SSH to work, but you can minimize the UTM window.
Part 8: Install NASM and the Build Tools
In the VS Code terminal (or over SSH), run the following.
sudo apt update
sudo apt install nasm build-essentialConfirm the installs and check that you are really on x86_64.
nasm -v
gcc --version
uname -muname -m should print x86_64. If it prints aarch64, you installed the ARM image by mistake. Go back to Part 2.
Part 9: Test It
Create a file called hello.asm in VS Code with the following contents.
global _start
section .data
msg db "Hello from x86_64!", 10
len equ $ - msg
section .text
_start:
mov rax, 1 ; sys_write
mov rdi, 1 ; stdout
mov rsi, msg
mov rdx, len
syscall
mov rax, 60 ; sys_exit
mov rdi, 0
syscallThen assemble, link, and run it from the terminal.
nasm -f elf64 hello.asm -o hello.o
ld hello.o -o hello
./helloIf you see Hello from x86_64!, you are all set. Continue to Hello World.
Shutting Down
To shut down the VM cleanly, run sudo shutdown now in the VM’s terminal, then close UTM. To start again, open UTM, select the VM, and press Play. You do not need the ISO again.