//---------------------------------------------------------------- // alphanum.s // // This program is for testing an assembly language function // which is intended to recognize 'alphanumeric' characters. // We think this function will help us to solve the in-class // exercise that was proposed at the conclusion of lesson 3. // // assemble using: $ as alphanum.s -o alphanum.o // and link using: $ ld alphanum.o -o alphanum // // programmer: ALLAN CRUSE // written on: 02 FEB 2009 //---------------------------------------------------------------- # manifest constants .equ stdin_ID, 0 # input-device (keyboard) .equ stdout_ID, 1 # output-device (screen) .equ sys_read, 0 # ID-number for 'read' .equ sys_write, 1 # ID-number for 'write' .equ sys_exit, 60 # ID-number for 'exit' .section .data msg1: .ascii "\nPlease type a sentence on the line below: \n" len1: .quad . - msg1 msg2: .ascii "\nYour letters and digits are marked by '+' \n" len2: .quad . - msg2 msg3: .ascii "\n" len3: .quad . - msg3 inbuf: .space 80 maxin: .quad . - inbuf .section .text #------------------------------------------------------------------ _start: # request user input mov $sys_write, %rax # service ID-number mov $stdout_ID, %rdi # device ID-number lea msg1, %rsi # message address mov len1, %rdx # message length syscall # enter the kernel # receive user input mov $sys_read, %rax # service ID-number mov $stdin_ID, %rdi # device ID-number lea inbuf, %esi # buffer address mov maxin, %rdx # buffer length syscall # enter the kernel mov %eax, maxin # save input count # replace alphanumeric character with '+' signs, and # non-alphanumeric characters with blank spaces ' ' lea inbuf, %rbx # point to buffer start mov maxin, %rcx # setup character count dec %rcx # exclude final newline nxchr: mov $' ', %al # setup a blank in AL xchg (%rbx), %al # swap with next char call isalphanum # is it alphanumeric? jnc nochg # no, leave the blank mov $'+', %al # else change to plus mov %al, (%rbx) # and overwrite blank nochg: inc %rbx # advance the pointer loop nxchr # again if chars left # display program output mov $sys_write, %rax # service ID-number mov $stdout_ID, %rdi # device ID-number lea inbuf, %rsi # message address mov maxin, %rdx # message length syscall # enter the kernel # explain program output mov $sys_write, %rax # service ID-number mov $stdout_ID, %rdi # device ID-number lea msg2, %rsi # message address mov len2, %rdx # message length syscall # enter the kernel # finish with one blank line mov $sys_write, %rax # service ID-number mov $stdout_ID, %rdi # device ID-number lea msg3, %rsi # message address mov len3, %rdx # message length syscall # enter the kernel # terminate this program mov $sys_exit, %rax # service ID-number mov $0, %rdi # setup exit-code syscall # enter the kernel #------------------------------------------------------------------ #------------------------------------------------------------------ isalphanum: # # This procedure examines the character it finds in the AL register; # it returns with the CF-flag set in case that character is either a # letter or a digit; otherwise, it returns with the CF-flag clear. # # is the character a digit? cmp $'0', %al # is AL below '0'? jb not_digit # yes, not a digit cmp $'9', %al # is AL above '9'? ja not_digit # yes, not a digit jmp yes_alpha # else alphanumeric not_digit: # is it an uppercase letter? cmp $'A', %al # is AL below 'A'? jb not_upper # yes, not uppercase cmp $'Z', %al # is AL above 'Z'? ja not_upper # yes, not uppercase jmp yes_alpha # else alphanumeric not_upper: # is it a lowercase letter? cmp $'a', %al # is AL below 'a'? jb not_lower # yes, not lowercase cmp $'z', %al # is AL above 'z'? ja not_lower # yes, not lowercase jmp yes_alpha # else alphanumeric not_lower: # setup the CF-flag for returning clc # Clear the CF-flag jmp now_return # and go to return yes_alpha: stc # Set the CF-flag jmp now_return # and go to return now_return: ret # return to caller #------------------------------------------------------------------ .global _start # visible entry-point .end # no more to assemble