Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tips on getting examples working on Windows 10 natively and on WSL #9

Open
AndrejMitrovic opened this issue Nov 30, 2022 · 2 comments

Comments

@AndrejMitrovic
Copy link

AndrejMitrovic commented Nov 30, 2022

Hi,

Just thought I'd share some tips here on how to get the examples working on Windows 10.

Running natively on Windows 10

For the very first hello.asm example on Page 25. Run these in batch / command-prompt / Windows Terminal:

rem Set up the 32-bit environment for VC
call "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars32.bat"

rem Assemble the hello.asm example
nasm -f win32 -d COFF_TYPE hello.asm

rem Compile & link
cl hello.obj ms/asm_io.obj driver.c legacy_stdio_definitions.lib

In particular linking with legacy_stdio_definitions.lib was necessary as otherwise _scanf / _printf / etc cannot be found.

Running on WSL

As for running it on WSL (Ubuntu on Win10), it's a bit more complicated. Most distros are 64-bit only, so the user needs to install gcc-multilib, make sure to link with 32-bit C library, add the ability for the OS to run 32-bit executables, and then finally an additional workaround is necessary to make this all work on WSL.

# Assemble the I/O file (or use the Makefile to assemble everything at once)
cd linux
nasm -felf32 -d ELF_TYPE asm_io.asm
cd ..

# Install GCC
sudo apt install build-essential

# Install 32-bit C standard library
sudo apt-get install gcc-multilib

# Assemble the hello example
# Note: it's not the same as the Windows example, it has different includes, symbols without _, etc.
nasm -felf32 hello.asm

# Compile the driver
gcc -c -m32 driver.c

# Use GCC to link it all together (much easier than using LD directly)
gcc -L /usr/lib32 -lc -m32 linux/asm_io.o driver.o hello-linux.o -ohello-linux

Finally to actually run the 32-bit executable you need additional work. Most of these tips taken from this Stackoverflow answer and from Github:

# Install qemu
sudo apt install qemu-user-static

# Ignore warnings on this one
sudo update-binfmts --install i386 /usr/bin/qemu-i386-static --magic \
'\x7fELF\x01\x01\x01\x03\x00\x00\x00\x00\x00\x00\x00\x00\x03\x00\x03\x00\x01\x00\x00\x00' \
--mask '\xff\xff\xff\xff\xff\xff\xff\xfc\xff\xff\xff\xff\xff\xff\xff\xff\xf8\xff\xff\xff\xff\xff\xff\xff'

# You MUST run this every time WSL starts. Probably best to add it to your .bashrc / .zshrc
sudo service binfmt-support start

# Add i386 architecture packages
sudo dpkg --add-architecture i386
sudo apt update
sudo apt install g++:i386

And then run the executable:

./hello-linux

Enter a number: 1
Enter another number: 2
Register Dump # 1
EAX = 00000003 EBX = 00000003 ECX = 663025FF EDX = FEFF9A44
ESI = FE7BA000 EDI = FE7BA000 EBP = FEFF99F8 ESP = FEFF99D8
EIP = FEFFB5C7 FLAGS = 0206                PF
Memory Dump # 2 Address = FEFFE1BC
FEFFE1B0 65 72 20 6E 75 6D 62 65 72 3A 20 00 59 6F 75 20 "er number: ?You "
FEFFE1C0 65 6E 74 65 72 65 64 20 00 20 61 6E 64 20 00 2C "entered ? and ?,"
You entered 1 and 2, the sum of these is 3

Finally always make sure to run sudo service binfmt-support start in WSL on the first start. Probably best to keep it in the .bashrc / .zshrc file in $HOME.

Hope this helps anyone else trying out this book on Windows.

Really appreciate the free book @pacman128, it's an awesome resource for learning asm!

Cheers!

@Saldef
Copy link

Saldef commented Apr 11, 2023

Thanks for the detailed tips and explanation Andrej.

I am not sure which version of WSL you were using, I was using WSL 2, and I did NOT need the additional workaround of using the QEMU emulator for the first program in page 25 to successfully run. The only extra steps that I needed was installing gcc-multilib and g++-multilib, and adding the -m32 option to the GCC.

I have actually submitted a pull request explaining why the -m32 option is needed, and raised an issue to be added to the text.

@AndrejMitrovic
Copy link
Author

I was using WSL1, maybe that's why I needed those workarounds. Cheers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants