2

I am teaching myself NASM and I'm having some trouble getting user input. (I already know MIPS and I'm familiar with x86). At first I was trying online compilers with the example code here, but although it printed to the screen it never actually paused to ask for input. I tried putting a number into the stdin window before running it, but that didn't work either.

The next thing I tried was running it straight from linux, so I installed NASM (I'm using Ubuntu, Windows Subsystem for Linux) but after compiling and getting an executable it just exited on the first system call and didn't print or ask for input. I tried running on my VM (Ubuntu 14.04) and that did work (yay!) but my VM is really slow so I try to avoid using it. Any idea why it would work there but not on my subsystem?

I decided to try switching to an IDE (I'm used to using Mars for MIPS) and installed SASM, which seems to be working except they have a separate user input window instead of asking for input as the program is running. Most of the online compilers I found have this as well and I'm a little confused as to why that is. I want to write a simple hangman program to get myself familiar with NASM but it doesn't really work with entering input before you run the program.

Any help at all would be appreciated, I don't know why the VM works but WSL doesn't and I'd really like to not use my VM, as my laptop is old and it's super slow.

Thank you!

The code I was originally running is:

section .data                           ;Data segment
   userMsg db 'Please enter a number: ' ;Ask the user to enter a number
   lenUserMsg equ $-userMsg             ;The length of the message
   dispMsg db 'You have entered: '
   lenDispMsg equ $-dispMsg                 

section .bss           ;Uninitialized data
   num resb 5

section .text          ;Code Segment
   global _start

_start:                ;User prompt
   mov eax, 4
   mov ebx, 1
   mov ecx, userMsg
   mov edx, lenUserMsg
   int 80h

   ;Read and store the user input
   mov eax, 3
   mov ebx, 2
   mov ecx, num  
   mov edx, 5          ;5 bytes (numeric, 1 for sign) of that information
   int 80h

   ;Output the message 'The entered number is: '
   mov eax, 4
   mov ebx, 1
   mov ecx, dispMsg
   mov edx, lenDispMsg
   int 80h  

   ;Output the number entered
   mov eax, 4
   mov ebx, 1
   mov ecx, num
   mov edx, 5
   int 80h  

   ; Exit code
   mov eax, 1
   mov ebx, 0
   int 80h

Compiling with:

nasm -f elf64 test.asm
ld test.o -o test

Then running:

./test

Ouptut of uname -m on subsystem: (same on VM)

x86_64

Output of file test on subsystem: (same on VM)

test: ELF 64-bit LSB executeable, x86-64, version 1 (SYSV), statically linked, not stripped

EDIT: So I figured it out! WSL doesn't support 32 bit at all, and you have to use the 64 bit syscall interface. I'm keeping this question up though, cause someone might find it useful and I'm also confused as to why input never worked on the online compilers, and why most online compilers and IDEs for NASM have a separate stdin input window.

lilibug1
  • 31
  • 5

1 Answers1

0

As you said in your comment to yourself, your problem was a lack of 32bit syscall(int 80) support in wsl.

Using binfmt and qemu-static you can run binaries from other linux targets. What qemu-static does is emulate the instruction set in usermode(i386 doesn't need much emulation on a x86), but translate the syscalls to be the ones your kernel uses natively.

Tried running on my VM (Ubuntu 14.04) and that did work (yay!) but my VM is really slow so I try to avoid using it.... Any help at all would be appreciated, I don't know why the VM works but WSL doesn't and I'd really like to not use my VM, as my laptop is old and it's super slow.

This should work great in your case as at least for 32bit x86 on 64bit x86 it very fast since it is an extremely thin layer.

For wsl it was first explored when somebody wanted to run arm binaries, but as a side effect it was noticed it would work great for 32bit x86 mode as well.

Here are the instructions on its requirements and how to get it working. It is fairly simple and easy to do.

Some additional information can be found in qemu's documentation on QemuUserEmulation.

With this not only can you try your hand at 32bit & nasm, but you could do adopt the method for other instruction sets like the mips you already know or learn some arm,sparc,ppc.

gmlime
  • 1,017
  • 8
  • 17