0

I'm trying to set up an Assembly Programming Environment on Windows. I do have Linux installed, but for curiosity sake, and also studying purposes for learning WSL, I'm trying to make it run through WSL2 on Windows 10.

I've tried to setup both Alpine and Ubuntu (base) installing only the following tools:

bash bash-doc bash-completion
util-linux pciutils usbutils coreutils binutils findutils grep

It was installed with either apk add or apt install.

Then I've wrote the following example from Programming Ground Up:

.section .data

.section .text
.globl _start

_start:
  movl $1, %eax
  movl $0, %ebx
  int $0x80

I did the compilation and link without any fancy flags, just the minimum like in the book example.

as exit.s -o exit.o
ld exit.o -o exit

I know that those calls like int $0x80 depends on architecture, operation system, etc.

It's returning Segmentation fault when I try to run it on the WSL image.

Searching around I've got to know that Segmentation fault is probably regarding the program not exiting the execution, like when a section doesn't have a ret statement. (In this case, int $0x80 should be enough for activating the kernel and returning/exiting by calling the value 1 set on ax register)

I thought it was because I'm trying to compile and run a 32bit ASM code in a 64bit machine. But, I did a ssh connection to a pub unix server, which is also a Ubuntu x86_64, and the same code could run without any problem.

Is it a WSL2 limitation? Or do this pubnix have something installed or configured for it to accept the 32bit code without any additional flag?

phuclv
  • 37,963
  • 15
  • 156
  • 475
jacksonbenete
  • 159
  • 1
  • 9
  • did you install [32-bit libs](https://stackoverflow.com/a/58980431/995714) in WSL2? – phuclv Jun 01 '21 at 03:50
  • 1
    [What happens if you use the 32-bit int 0x80 Linux ABI in 64-bit code?](https://stackoverflow.com/q/46087730/995714) – phuclv Jun 01 '21 at 03:51
  • 2
    Are you *sure* you have WSL2, not WSL1? WSL1 is known to not definitely not have any 32-bit support. In the distro you installed in WLS2, have you checked that it was built with CONFIG_IA32_EMULATION=y? Even though the 32-bit int 0x80 ABI is usable from 64-bit user-space, it's still part of that optional feature. – Peter Cordes Jun 01 '21 at 04:08
  • 1
    (Note that for the PGU examples, normally you'd want to assemble + link into *32-bit* executables: `gcc -m32 -nostdlib -static foo.S`. Or manually, `as --32` and `ld -melf_i386`. Otherwise you won't be able to use instructions like `push %edi`, and stack addresses won't work as pointer args to system calls like read/write. e.g. `mov %rsp, %rcx` / `int $0x80` will return `-EFAULT` because the 32-bit ABI only looks at ECX, not RCX.) – Peter Cordes Jun 01 '21 at 04:29
  • Thank you @phuclv, there was no need to install the 32-bit libs, but it's very interesting to know details about `int 0x80` on 64-bit code. – jacksonbenete Jun 01 '21 at 14:31
  • @PeterCordes you're right. I was not sure WSL2 was being used although I was sure it was installed. This was the source of the problem, since it's installed I thought that any image I create would be running at WSL2 already, but I had to set it to be the default `wsl --set-default-version 2`. Now it works as expected even without the `as --32` and `ld -melf_i386` flags. It was my lack of understanding of WSL. – jacksonbenete Jun 01 '21 at 14:35
  • 2
    Yes *this* program will work when built into a 64-bit executable (if your kernel has CONFIG_IA32_EMULATION, which WSL1 effectively doesn't), for the reasons explained in [What happens if you use the 32-bit int 0x80 Linux ABI in 64-bit code?](https://stackoverflow.com/q/46087730) - that system call doesn't use any pointers or structs. My point was that other programs will require that to work as expected. – Peter Cordes Jun 01 '21 at 19:42

1 Answers1

2

The WSL2 do have support to 32-bit libraries and system calls.

So it's a nice way of programming assembly on Windows without the need for dual-boot and assembly emulators.

But it is a mistake to assume that since WSL2 is installed, it's also being used.

  • If you don't have WSL2 installed you need to install it.

If you already have WSL2 installed, you can either convert a WSL1 image to WSL2, or set the WSL version to the version you want (WSL2) to be used when creating/importing your next image.

(In my case, Docker Desktop for Windows automatically installed WSL2 for me)

  • You can check if your image is WSL1 or WSL2 with:
wsl -l -v
  • You can create a WSL2 image by setting WSL2 to be used.
wsl --set-default-version 2

Everytime you create a new image or import, it will be set as WSL2. If you want to go back to WSL1 you can wsl --set-default-version 1.

Now you can create a new image as usual.

  • If your image is version 1 already, you can convert it to version 2 with:
wsl --set-version image_name 2

(Converting an image may take a long time)

  • Instead, you can export your current image, and import/create it again as a WSL2 version, so you can keep both version if needed.
wsl --export current-image image-backup.tar
mkdir new-folder
wsl --import newimg new-folder image-backup.tar

(Exporting and Importing will keep your $HOME and files, it's like making a backup of the entire image)

jacksonbenete
  • 159
  • 1
  • 9