//---------------------------------------------------------------- // toupper.s // // This interactive program shows one possible way in which // you can use assembly language to scan an array of ascii- // codes, looking for any occurrences of lowercase letters, // and converting any found to their uppercase equivalents. // The program's loop relies for its correctness on the way // in which terminal-input is normally handled by the Linux // operating system (i.e., the so called 'canonical' input) // which assures that the 'read' system-call will return at // least one character (e.g., a 'newline' ascii-code '\n'). // So a program which modified the 'termios' data-structure // in order to use 'noncanonical' terminal-input might need // to substitute a 'while-loop' in place of our 'do-loop'. // // assemble using: $ as toupper.s -o toupper.o // and link using: $ ld toupper.o -o toupper // // programmer: ALLAN CRUSE // written on: 17 APR 2006 //---------------------------------------------------------------- # manifest constants .equ MAXIN, 80 # maximum length of input .equ STDIN, 0 # device-ID for keyboard .equ STDOUT, 1 # device-ID for display .equ sys_exit, 1 # service-ID for 'exit' .equ sys_read, 3 # service-ID for 'read' .equ sys_write, 4 # service-ID for 'write' .section .data prompt: .ascii "Please type in a short message, " .ascii "then press the -key: \n" msglen: .int . - prompt # length of prompt string buffer: .space MAXIN # buffer holds user input icount: .int 0 # counts the keys pressed .section .text _start: # display the prompting message mov $sys_write, %eax # system-call ID-number mov $STDOUT, %ebx # device-file ID-number lea prompt, %ecx # message's address mov msglen, %edx # message's length int $0x80 # enter Linux kernel # receive the user's response mov $sys_read, %eax # system-call ID-number mov $STDIN, %ebx # device-file ID-number lea buffer, %ecx # buffer's address mov $MAXIN, %edx # buffer's length int $0x80 # enter Linux kernel mov %eax, icount # store input's length # do-loop: converts lowercase ascii-codes to uppercase xor %ebx, %ebx # initialize array-index nxchr: cmpb $'a', buffer(%ebx) # code preceeds 'a'? jb notlc # yes, not lowercase cmpb $'z', buffer(%ebx) # code follows 'z'? ja notlc # yes, not lowercase subb $'a', buffer(%ebx) # use letter's offset addb $'A', buffer(%ebx) # in uppercase sequence notlc: inc %ebx # increment array-index cmp icount, %ebx # index out-of-bounds? jb nxchr # not yet, do another # show the input-string without any lowercase letters mov $sys_write, %eax # system-call ID-number mov $STDOUT, %ebx # device-file ID-number lea buffer, %ecx # buffer's address mov icount, %edx # buffer's length int $0x80 # enter Linux kernel # terminate the program mov $sys_exit, %eax # system-call ID-number mov $0, %ebx # value for 'exit-code' int $0x80 # enter Linux kernel .global _start # make entry-point visible .end # nothing more to assemble