//---------------------------------------------------------------- // password.s // // This program prompts the user to enter a secret password, // then replies with a diagnostic message. // // programmer: ALLAN CRUSE // written on: 01 SEP 2003 // correction: 16 SEP 2003 -- fixed 'address-comparison' bug //---------------------------------------------------------------- # manifest constants .equ MAXIN, 20 .equ FALSE, 0 .equ TRUE, ~0 .section .data target: .ascii "USFDONS\n" pwsize: .int . - target prompt: .asciz "\nPlease type in the secret password: " success:.string "Correct password -- access granted.\n" failure:.string "Invalid password -- access refused.\n" buffer: .space MAXIN valid: .byte FALSE .section .text #----------------------------------------------------------------- main: call obtain_password call verify_validity call notify_the_user call grant_or_refuse ret #----------------------------------------------------------------- obtain_password: # # This function requests the user to type the secret password, # then stores the user's response in a character-array buffer. # call request_input call receive_reply ret #----------------------------------------------------------------- verify_validity: # # This procedure compares the array of input-characters typed # by the user with the 'target' array which holds the correct # password. The 'valid' flag does not remain TRUE unless all # of their ascii codes agree. # xorl %esi, %esi # initial array index movl $TRUE, valid # starting assumption next: movb buffer(%esi), %al # get next input-char cmpb target(%esi), %al # it matches target? je incr # yes, advance index movl $FALSE, valid # else flag adjusted incr: incl %esi # advance array index cmpl %esi, pwsize # end-of-array yet? jg next # <-- bug fixed # no, check another ret #----------------------------------------------------------------- #----------------------------------------------------------------- request_input: # # This function prints an initial message which asks the user # to type in the secret password. # push $prompt # argument to function call printf # call runtime library addl $4, %esp # discard the argument ret #----------------------------------------------------------------- receive_reply: # # This function reads in the characters that are typed by the # user and returns (when the user hits the key) with # the ascii character-codes stored in an array named 'buffer'. # push stdin # argument #3 push $MAXIN # argument #2 push $buffer # argument #1 call fgets # call runtime library addl $12, %esp # discard arguments ret #----------------------------------------------------------------- notify_the_user: # # This procedure prints a diagonistic message, based on the # value (TRUE or FALSE) it finds stored in the 'valid' flag. # movl $success, %eax # setup message-address cmpl $TRUE, valid # is it the proper one? je msgok # yes, proceed to print movl $failure, %eax # no, use other message msgok: push %eax # function's argument call puts # call runtime library addl $4, %esp # discard the argument ret #----------------------------------------------------------------- grant_or_refuse: # # This procedure checks the value of the 'valid' flag and # leaves this function in case 'valid' is TRUE; otherwise # it continues executing here in an infinite loop so that # the user is thus prevented from making further progress. # cmpl $TRUE, valid # was password valid? je return # yes, then ok to exit freeze: jmp freeze # else continue here return: ret #----------------------------------------------------------------- .globl main .end