To make your programs more attractive to the eye and show off with your skills,
you can make the keyboard LEDs, showing the state of the
Num Lock, Caps Lock, Scroll Lock keys, flash in some way.
Now I'll show you how to do it.
To manipulate a character device (the keyboard) use the sys_ioctl system call (number 54). First you need to know what commands to use. To get those, read the /usr/include/linux/kd.h file or the manual, if you have the ioctl_list page. There we have:
#define KDGETLED 0x4B31 /* get current LED status */ #define KDSETLED 0x4B32 /* set new LED status */ #define LED_SCR 0x01 /* scroll lock */ #define LED_NUM 0x02 /* num lock */ #define LED_CAP 0x04 /* caps lock */
One of the first two values will be
put into ECX.
Meanwhile, EBX should contain a descriptor of /dev/console open
for writing or the value 1, meaning the standard output device - STDOUT.
EDX will contain the last parameter: a value in the range 0-7, if we want to set the LED state,
or an address of a DWORD variable, which will receive the current LED state (also in the
range 0-7).
Now we can see what our program should do: save the current LED state, change them as you like
(and make it last - do pauses), bring back the old state.
Here's how such a program could look like (using my library isn't necessary - the comments
tell what to change.
; Program manipulates the keyboard LEDs ; ; Author: Bogdan D. ; Contact: bogdandr (at) op (dot) pl ; ; nasm -f elf klaw.asm ; ld -s -o klaw klaw.o section .text ; you don't have to use these: %include "bibl/incl/linuxbsd/nasm/n_system.inc" %include "bibl/incl/linuxbsd/nasm/n_const.inc" %define KDGETLED 0x4b31 %define KDSETLED 0x4b32 global _start _start: ; 1. open /dev/console, in write-only mode or use STDOUT mov eax, sys_open ; sys_open = 5 (open the file) mov ebx, konsola ; address of the file name mov ecx, O_WRONLY ; O_WRONLY = 01 mov edx, 777q ; RWX for all int 80h cmp eax, 0 jge .ok ; continue if no error ; if error, use STDOUT mov eax, stdout ; stdout = 1 ; 2. get current LED state .ok: mov ebx, eax ; EBX = file descriptor mov eax, sys_ioctl ; sys_ioctl = 54 - device manipulation mov ecx, KDGETLED ; get led state mov edx, stare_diody ; address of a DWORDa for the ; current LED state int 80h mov eax, sys_ioctl ; sys_ioctl = 54 mov ecx, KDSETLED ; set LED state mov edx, 7 ; all set to "on" int 80h mov cx, 7 mov dx, 0a120h ; delay for half a second call pauza ; bring back the old state mov eax, sys_ioctl mov ecx, KDSETLED ; set LED state mov edx, [stare_diody] ; EDX = previous LED state int 80h cmp ebx, stdout ; did we open the console or STDOUT? jle .koniec ; don't close the STDOUT mov eax, sys_close ; close the open console file int 80h .koniec: wyjscie ; ; mov eax, 1 ; xor ebx, ebx ; int 80h pauza: ; procedure pausing for CX:DX miliseconds push ebx push ecx push edx mov ax, cx shl eax, 16 mov ebx, 1000000 mov ax, dx ; EAX = CX:DX xor edx, edx div ebx ; divide CX:DX by 1 million mov [t1 + timespec.tv_sec], eax ; EAX = number of seconds mov ebx, 1000 mov eax, edx ; EAX = number of microseconds left mul ebx mov [t1 + timespec.tv_nsec], eax ; EAX = number of nanoseconds mov eax, sys_nanosleep ; function number 162 mov ebx, t1 mov ecx, t2 int 80h pop edx pop ecx pop ebx ret section .data stare_diody dd 0 konsola db "/dev/console",0 ; The timespec structure is defined in n_system.inc (from my library) ;struc timespec ; .tv_sec: resd 1 ; .tv_nsec: resd 1 ;endstruc t1 istruc timespec t2 istruc timespec
Further experiments are left as an excercise for the user. Remember there are 8 different possible combinations for the LED state and you can make the different durations between state changes.
Have fun.