Search code examples
linuxassemblylinux-kernelkeyboard-eventsgnu-assembler

Reading keyboard events from /dev/input/event* in assembler


The problem is to read from device directly (can't read from stdin). That's quite a simple task to implement in C. But I can't find a way to do the same thing in assembler. Event layout is:

struct input_event {
    struct timeval time;
    unsigned short type;
    unsigned short code;
    unsigned int value;
};

So, I've tried this:

.section .data
file:
    .asciz "/dev/input/event0"

# event structure
event:
time:
    .octa 0
type:
    .short 0
code:
    .short 0
value:
    .int 0

.section .text
    .globl _start

_start:
    # open /dev/input/event0 for reading
    movl $5, %rax               # sys_open
    movl $file, %rbx            # put path in rbx
    movl $00, %rcx              # readonly flag
    movl $04020, %rdx           # open mode
    syscall                   
    movl %rax, %rsp             # put file descriptor on stack
...

So, sys_open puts -14 in %rax, "Bad address" error. What's the problem to read from /dev/input/event* (with root priveleges of course)? What is a proper way to do that? And is it okay to read structures the way I'm going to do that (in bunch of bytes at the label "event")?


Solution

  • That shouldn't even assemble, please don't use conflicting size suffixes ... movl for a 64 bit operation makes no sense even if you are lucky that the assembler accepts it (mine doesn't, and rightly so). Also your problem is not with reading the events. You can't even open the file, so you should have focused your question on that. The reason it doesn't work is that the function number for open is 2, 5 means fstat. Also, the arguments should be placed in rsi, rdi and rdx (but note that mode does not have to be passed if you don't ask for O_CREAT):

    movl $2, %eax              # sys_open
    movabsq $file, %rdi        # path
    movl $00, %esi             # readonly flag
    syscall
    

    movl %rax, %rsp is also a bad idea, you probably wanted something else like movq %rax, -8(%rsp) or whatever is appropriate.

    PS: at least on my system you need root privileges to open /dev/input/event0.