My Daily Gist | Ferdinand Silva


Linux x86-64 Assembly Language termios Sample Code

 
%define STDIN_FILENO 0
%define TCSAFLUSH 2
%define VMIN 6
%define VTIME 5
%define BRKINT 0x2
%define ICRNL 0x100
%define INPCK 0x10
%define ISTRIP 0x20
%define IXON 0x400
%define OPOST 0x1
%define CS8 0x30
%define ECHO 0x8
%define ICANON 0x2
%define IEXTEN 0x8000
%define ISIG 0x1
%macro get_termios 1
mov rdi, STDIN_FILENO
mov rsi, %1
call tcgetattr
mov rdi, err_tcgetattr
cmp rax, -1
je die
%endmacro
%macro set_termios 1
mov rdi, STDIN_FILENO
mov rsi, TCSAFLUSH
mov rdx, %1
call tcsetattr
mov rdi, err_tcsetattr
cmp rax, -1
je die
%endmacro
%macro print 1
mov rdi, %1
xor rax, rax
call printf
%endmacro
global main
extern printf, perror, tcsetattr, tcgetattr, read, iscntrl
section .data
err_read:
db "read", 0
err_tcsetattr:
db "tcsetattr", 0
err_tcgetattr:
db "tcgetattr", 0
output1:
db "%d", 0xd, 0xa, 0
output2:
db "%d ('%c')", 0xd, 0xa, 0
ctrl_check:
dd 0x1f
intro:
db "Type from your keyboard. Press CTRL + q to exit.", 0xd, 0xa, 0
struc TERMIOS
c_iflag: resd 1
c_oflag: resd 1
c_cflag: resd 1
c_lflag: resd 1
c_cc: resb 255
endstruc
orig_termios: istruc TERMIOS
at c_iflag, dd 0
at c_oflag, dd 0
at c_cflag, dd 0
at c_lflag, dd 0
at c_cc, db ""
iend
raw_termios: istruc TERMIOS
at c_iflag, dd 0
at c_oflag, dd 0
at c_cflag, dd 0
at c_lflag, dd 0
at c_cc, db ""
iend
char_quit:
dd 'q'
section .bss
input_char:
resb 1
section .txt
main:
print intro
get_termios orig_termios
get_termios raw_termios
;enable raw mode
;set c_iflag
mov r15, BRKINT
or r15, ICRNL
or r15, INPCK
or r15, ISTRIP
or r15, IXON
not r15
mov r14, [raw_termios + c_iflag]
and r14, r15
mov [raw_termios + c_iflag], r14
;set c_oflag
mov r15, OPOST
not r15
mov r14, [raw_termios + c_oflag]
and r14, r15
mov [raw_termios + c_oflag], r14
;set c_cflag
mov r15, CS8
mov r14, [raw_termios + c_cflag]
or r14, r15
mov [raw_termios + c_cflag], r14
;set c_lflag
mov r15, ECHO
or r15, ICANON
or r15, IEXTEN
or r15, ISIG
not r15
mov r14, [raw_termios + c_lflag]
and r14, r15
mov [raw_termios + c_lflag], r14
;set VMIN and VTIME
mov r15, raw_termios + c_cc
mov byte [r15 + VMIN], 0
mov byte [r15 + VTIME], 1
mov [raw_termios + c_cc], r15
set_termios raw_termios
;end of enable raw mode
main_loop:
mov [input_char], byte 0
mov rdi, STDIN_FILENO
mov rsi, input_char
mov rdx, 1
call read
mov rdi, err_read
cmp rax, -1
je die
mov rdi, [input_char]
call iscntrl
cmp rax, 0
je isnotctrl
cmp byte [input_char], 0
je ender
mov rsi, [input_char]
print output1
ender:
mov r11, [ctrl_check]
and r11, [char_quit]
cmp r11, [input_char]
je break
jmp main_loop
isnotctrl:
mov rdx, [input_char]
mov rsi, [input_char]
print output2
jmp ender
break:
set_termios orig_termios
mov rdi, 0
jmp exit
die:
call perror
mov rdi, 1
call exit
exit:
mov rax, 0x3c
syscall
ret
view raw test.asm hosted with ❤ by GitHub