1

I am currently studying Computer Architecture and one core topic is assembler. For some reason the prof's example code doesn't work on my computer. I am using a 64-Bit Linux-Subsystem for Windows to assemble, compile, debug and execute the code. Here is the example:

section .data

msg: db "Hello world!", 0x0a
errmsg: db "Error!", 0x0a

section .bss

buf1: resb 40
buf2: resb 20

section .text
global _start

write_msg:
mov eax, 4 ; write syscall
mov ebx, 1 ; to stdout
mov ecx, msg ; buffer to write
mov edx, 13 ; number of bytes to write
int 80h ; kernel interrupt
ret

_start:
call write_msg
mov eax, 1 ; exit syscall
mov ebx, 0 ; exit code 0
int 80h ; kernel interrupt

I am assembling, compiling and executing the code as follows:

nasm -g -f elf64 helloworld.asm
ld -m elf_x86_64 -static -o helloworld helloworld.o
./helloworld

When doing so I simply get the error message:

Segmentation fault (core dumped)

Then I tried debugging it with GDB to find the cause of the error (even though this example was given to us by our professor and it works perfectly fine on a friends pc):

gdb helloworld

set disassembly-flavor intel

break *write_msg+1

run

And I also get an error message which says:

warning: opening /proc/PID/mem file for lwp 223.223 failed: No such file or directory
Warning:
Cannot insert breakpoint 1.
Cannot access memory at address 0x401001

I have googled to try to find something that explains and fixes this error but I couldnt find anything.

Help would be appreciated.

FarbKlexx
  • 13
  • 2
  • Is that the correct syntax for setting a breakpoint? Why break at `write_msg` and not at `_start`? – Jim Rhodes Jan 10 '23 at 19:10
  • Same problem occurs when breaking at _start – FarbKlexx Jan 10 '23 at 19:13
  • 1
    That is 32 bit code, that will not work in a 64 bit WSL. – Jester Jan 10 '23 at 19:15
  • Is there a documentation where I can see the syntax differences between 32 and 64 bit? – FarbKlexx Jan 10 '23 at 19:21
  • 1
    The syntax is the same, but 64 bit uses different way to do system calls. You should be able to find [64 bit hello world](https://stackoverflow.com/questions/19743373/linux-x86-64-hello-world-and-register-usage-for-parameters) easily. – Jester Jan 10 '23 at 19:22
  • Your first instruction isn't 1 byte long, so `break *write_msg+1` isn't a good place to insert a breakpoint. IDK why it failed to even open the process's `/proc/PID/mem` file, though, once GDB started a child process (when you did `run`). Use `starti` to stop before the first instruction in the new process without needing a breakpoint. – Peter Cordes Jan 11 '23 at 04:56

1 Answers1

0

Currently WSL is only 64-bit and 32-bit code simply dose not work. Secondly, in 64-bit mode you should use 64-bit registers and syscall instead of int 0x80. If you would like to use 32-bit programs upgrade to WSL2.

Markian
  • 322
  • 1
  • 12
  • If you use WSL2 (you can upgrade WSL containers to WSL2) the Linux kernels are built with IA32 emulation and do support the running of 32-bit programs, where as WSL does not. You should still build 32-bit programs as 32-bit and 64-bit programs as 64-bit as mixing 32-bit `int 0x80` with 64-bit code even in WSL2 can be problematic since 64-bit pointers can't be passed to 32-bit `int 0x80` system calls. – Michael Petch Jan 10 '23 at 22:11
  • `syscall` isn't a drop-in replacement for `int 0x80`, you have to use different call-numbers and registers. There's a canonical Q&A about that, [What happens if you use the 32-bit int 0x80 Linux ABI in 64-bit code?](https://stackoverflow.com/q/46087730), so I closed this question as a duplicate. – Peter Cordes Jan 11 '23 at 04:58
  • I said that you should use 64-bit registers – Markian Jan 11 '23 at 14:48