//---------------------------------------------------------------- // noecho.s // // This program shows how to inhibit echoing of user-input. // // assemble using: $ as noecho.s -o noecho.o // and link using: $ ld noecho.o -o noecho // // programmer: ALLAN CRUSE // written on: 12 MAR 2006 //---------------------------------------------------------------- # manifest constants .equ sys_exit, 1 .equ sys_read, 3 .equ sys_write, 4 .equ sys_ioctl, 54 .equ TCGETATTR, 0x5401 .equ TCSETATTR, 0x5402 .equ TERMIOS_SIZE, 36 .equ ECHO, 0x00000008 .equ ECHONL, 0x00000040 .equ MAX_INPUT, 40 .equ STDIN_FILENO, 0 .equ STDOUT_FILENO, 1 .equ c_lflag, 12 .section .data prompt: .ascii "\n\tPlease type in your name: " msglen: .int . - prompt # number of message bytes thanks: .ascii "\n\tThank you, " # sign-off message-format buffer: .zero MAX_INPUT # to insure null-padding .ascii "\n" # to append extra newline buflen: .int . - thanks # size of signoff message .section .bss ttyorig: .space TERMIOS_SIZE # initial struct termios ttywork: .space TERMIOS_SIZE # working struct termios .section .text #----------------------------------------------------------------- _start: call save_termios # save initial settings call echo_inhibit # install modifications call obtain_input # get user's keystrokes call process_data # name gets capitalized call print_output # show sign-off message call echo_enabled # restore initial state call exit_program # return to Linux shell #----------------------------------------------------------------- #----------------------------------------------------------------- save_termios: # # This procedure acquires a copy of current terminal settings. # mov $sys_ioctl, %eax # system-call ID-number mov $STDIN_FILENO, %ebx # device-file ID-number mov $TCGETATTR, %ecx # ioctl function-number lea ttyorig, %edx # address for structure int $0x80 # invoke kernel service ret # return to caller #----------------------------------------------------------------- echo_inhibit: # # This procedure makes a copy of the initial terminal settings, # modifies its settings for the ECHO and ECHONL bits within the # 'c_lflag' field, and installs the adjusted terminal settings. # # copy the 'origtty' data-structure into 'worktty' movl $ttyorig, %esi # point %esi to source movl $ttywork, %edi # point %edi to dest'n movl $TERMIOS_SIZE, %ecx # number of bytes to copy cld # specify forward copying rep movsb # copy source to dest'n # modify some bits in our working copy of the structure movl $c_lflag, %edi # c_lflag field's offset andl $~ECHO, ttywork(%edi) # turn off the ECHO bit orl $ECHONL, ttywork(%edi) # turn on the ECHONL bit # now activate our modified terminal settings mov $sys_ioctl, %eax # system-call ID-number mov $STDIN_FILENO, %ebx # device-file ID-number mov $TCSETATTR, %ecx # ioctl function-number lea ttywork, %edx # address for structure int $0x80 # invoke kernel service ret # return to caller #----------------------------------------------------------------- obtain_input: # prompt the user for keyboard input mov $sys_write, %eax # system-call ID-number mov $STDOUT_FILENO, %ebx # device-file ID-number lea prompt, %ecx # message's address mov msglen, %edx # message's length int $0x80 # invoke kernel service # read keyboard input into our buffer mov $sys_read, %eax # system-call ID-number mov $STDIN_FILENO, %ebx # device-file ID-number lea buffer, %ecx # buffer's address mov $MAX_INPUT, %edx # buffer's length int $0x80 # invoke kernel service ret # return to caller #----------------------------------------------------------------- #----------------------------------------------------------------- process_data: # first letter in the buffer should not be lowercase cmpb $'a', buffer # ascii-code is below 'a'? jb asis # yes, it's not lowercase cmpb $'z', buffer # ascii-code is above 'z'? ja asis # yes, it's not lowercase # ok, it IS lowercase, so we change it andb $0xDF, buffer # else convert to uppercase asis: ret # return to caller #----------------------------------------------------------------- print_output: # display the sign-off message mov $sys_write, %eax # system-call ID-number mov $STDOUT_FILENO, %ebx # device-file ID-number lea thanks, %ecx # message's address mov buflen, %edx # message's length int $0x80 # invoke kernel service ret # return to caller #----------------------------------------------------------------- echo_enabled: # # This procedure will reinstall the original terminal settings. # mov $sys_ioctl, %eax # system-call ID-number mov $STDIN_FILENO, %ebx # device-file ID-number mov $TCSETATTR, %ecx # ioctl function-number lea ttyorig, %edx # address for structure int $0x80 # invoke kernel service ret # return to caller #----------------------------------------------------------------- exit_program: mov $sys_exit, %eax # system-call ID-number mov $0, %ebx # value for 'exit-code' int $0x80 # invoke kernel service #----------------------------------------------------------------- .global _start # make entry-point public .end # no more to be assembled