Using "C" functions is not any fun, we are using Assembly, let's do it the right way!
Linux terminal programs start in "Cooked" mode, to do this properly, you need to change to "raw" mode. Here is some code to get you going:
ICANON equ 1<<1
ECHO equ 1<<3
sys_exit equ 1
sys_read equ 3
sys_write equ 4
stdin equ 0
stdout equ 1
global _start
section .data
szAsterisk db "*"
szLF db 10
section .bss
lpBufIn resb 2
lpPassIn resb 24
termios resb 36
section .text
_start:
call echo_off
call canonical_off
xor esi, esi
.GetCode:
cmp esi, 24
je .PassTooBig
call GetKeyCode
mov al, byte[lpBufIn]
cmp al, "Q"
je .Done
cmp al, 10
je .Continue
mov byte [lpPassIn + esi], al
call PrintAsterisk
inc esi
jmp .GetCode
.Continue:
mov byte [lpPassIn + esi], 10 ; change 10 to 0 to null terminate
;~ for testing purposes
;~ #####################################
inc esi ;~ #
;~ #
mov edx, 1 ;~ #
mov ecx, szLF ;~ #
mov eax, sys_write ;~ #
mov ebx, stdout ;~ #
int 80H ;~ #
;~ #
mov edx, esi ;~ #
mov ecx, lpPassIn ;~ #
mov eax, sys_write ;~ #
mov ebx, stdout ;~ #
int 80H ;~ #
;~ #####################################
;~ Compare passowrds here!!!
jmp .Done
.PassTooBig:
;~ Entered password too big!
.Done:
call echo_on
call canonical_on
mov eax, sys_exit
xor ebx, ebx
int 80H
;~ #########################################
GetKeyCode:
mov eax, sys_read
mov ebx, stdin
mov ecx, lpBufIn
mov edx, 1
int 80h
ret
;~ #########################################
PrintAsterisk:
mov edx, 1
mov ecx, szAsterisk
mov eax, sys_write
mov ebx, stdout
int 80H
ret
;~ #########################################
canonical_off:
call read_stdin_termios
; clear canonical bit in local mode flags
mov eax, ICANON
not eax
and [termios+12], eax
call write_stdin_termios
ret
;~ #########################################
echo_off:
call read_stdin_termios
; clear echo bit in local mode flags
mov eax, ECHO
not eax
and [termios+12], eax
call write_stdin_termios
ret
;~ #########################################
canonical_on:
call read_stdin_termios
; set canonical bit in local mode flags
or dword [termios+12], ICANON
call write_stdin_termios
ret
;~ #########################################
echo_on:
call read_stdin_termios
; set echo bit in local mode flags
or dword [termios+12], ECHO
call write_stdin_termios
ret
;~ #########################################
read_stdin_termios:
mov eax, 36h
mov ebx, stdin
mov ecx, 5401h
mov edx, termios
int 80h
ret
;~ #########################################
write_stdin_termios:
mov eax, 36h
mov ebx, stdin
mov ecx, 5402h
mov edx, termios
int 80h
ret
At program start, we turn off character echo by calling echo_off and to enter raw mode, call canonical_off
*** VERY IMPORTANT ***
Before you exit your program, turn echo back on, and cooked mode back on!!!
call echo_on
call canonical_on