1
votes

I'm attempting to write a simple program which grabs a number of characters from stdin. For the sake of brevity, the relevant code is:

mov $3, %rax    # sys_read = 3
mov $0, %rbx    # stdin fd = 0
mov $b, %rcx    # '.lcomm b, 32' declared in .bss section
mov $32,%rdx    # size_t
# syscall
int $0x80

When I use int $0x80 the program functions as intended, however with syscall it segfaults. I read that it has something to do with the fact that using an interrupt requires the kernel to remember the state of the machine, while syscall does not honour that requirement, i.e., the kernel handles it in its own time. I'm not sure if this is the real reason - I would assume that syscall does something to the registers such that sys_read fails.

I also read from a previous question posted here that "syscall is the default way of entering the kernel" and that "int 0x80 is the legacy way to invoke a system call and should be avoided." (Link)

I can't really find any good documentation on this, so any input would be appreciated.

Edit: typo

1
syscall should work on a 64-bit system, but you need different sys_call numbers and parameters in different registers. Funny how int 80h is not recommended... but seems to work - even on a 64-bit system! You've got a "mixed bag" of 64-bit registers and 32-bit system call numbers and parameters.Frank Kotler
Ahh okay, thank you. The $b and $0 go into registers rsi and rdi, respectively.jtx

1 Answers

0
votes

Check this question. On x86_64 the correct exit system call is $60 which should be in %rax.

 mov $60, %rax
 mov $0, %rdi 
 syscall