In DOS, this is easy - there's a "no echo input" interrupt service for int 21h (two of them, in fact). I don't know how Windows does it - SetConsoleMode, I suspect. As I recall, you're using Linux - 64-bit Linux. I don't know that one, either, but I do have a 32-bit routine which may help. It'll need some adjustment for 64-bit, but I suspect it's pretty similar...
; ...
; misc. equates
%define NL 10
%define STDIN 0
%define STDOUT 1
; sys_calls
%define SYS_EXIT 1
%define SYS_READ 3
%define SYS_WRITE 4
%define SYS_IOCTL 54
;...
;-----------------------------
; ioctl subfunctions
%define TCGETS 0x5401 ; tty-"magic"
%define TCSETS 0x5402
; flags for 'em
%define ICANON 2 ;.Do erase and kill processing.
%define ECHO 8 ;.Enable echo.
struc termios
alignb 4
.c_iflag: resd 1 ; input mode flags
.c_oflag: resd 1 ; output mode flags
.c_cflag: resd 1 ; control mode flags
.c_lflag: resd 1 ; local mode flags
.c_line: resb 1 ; line discipline
.c_cc: resb 19 ; control characters
endstruc
;---------------------------------
getc:
push ebp
mov ebp, esp
sub esp, termios_size ; make a place for current kbd mode
push edx
push ecx
push ebx
mov eax, SYS_IOCTL ; get current mode
mov ebx, STDIN
mov ecx, TCGETS
lea edx, [ebp - termios_size]
int 80h
; monkey with it
and dword [ebp - termios_size + termios.c_lflag], ~(ICANON | ECHO)
mov eax, SYS_IOCTL
mov ebx, STDIN
mov ecx, TCSETS
lea edx, [ebp - termios_size]
int 80h
xor eax, eax
push eax ; this is the buffer to read into
mov eax, SYS_READ
mov ebx, STDIN
mov ecx, esp ; character goes on the stack
mov edx, 1 ; just one
int 80h ; do it
; restore normal kbd mode
or dword [ebp - termios_size + termios.c_lflag], ICANON | ECHO
mov eax, SYS_IOCTL
mov ebx, STDIN
mov ecx, TCSETS
lea edx, [ebp - termios_size]
int 80h
pop eax ; get character into al
pop ebx ; restore caller's regs
pop ecx
pop edx
mov esp, ebp ; leave
pop ebp
ret
;-------------------------
This is defective in several ways. I only use one copy of the termios structure, modify it in place, set the new configuration, then modify it back... This ASSumes that we had a "normal" configuration to begin with - if not, I've just messed it up. Better to use two copies. I've seen code that uses TCGETS twice, but I suspect it's much faster to copy the structure. Modify the copy and TCSETS from that, then TCSETS to the original when we're done. The other thing is that if we recieve certain signals while we're waiting for a key, it'll put us back in "wait for 'enter' " (and echo) mode. SIGSUSP for sure, and I think SIGWINCH will do it, too. I can live with this for my naive purposes, but it needs a lot of improvement! This counts as "teaching sloppy solutions to beginners" and I really shouldn't do it! You'll need to print the '*' for each character by normal methods, of course.
Give it a shot, and ask again if you have trouble.
Best,
Frank