//---------------------------------------------------------------- // reverse.s // // This program shows how the stack can be used to rearrange // characters that are stored in an array in backward order. // (This idea is useful when you write a language compiler.) // // assemble using: $ as reverse.s -o reverse.o // and link using: $ ld reverse.o -o reverse // // programmer: ALLAN CRUSE // written on: 03 FEB 2005 //---------------------------------------------------------------- # manifest constants .equ stdin_ID, 0 # input-device (keyboard) .equ stdout_ID, 1 # output-device (screen) .equ sys_exit, 1 # ID-number for 'exit' .equ sys_read, 3 # ID-number for 'read' .equ sys_write, 4 # ID-number for 'write' .section .data msg1: .ascii "\nPlease type a sentence on the line below: \n" len1: .int . - msg1 msg2: .ascii "\nHere is what you typed in backward order: \n" len2: .int . - msg2 msg3: .ascii "\n" len3: .int . - msg3 inbuf: .space 80 maxin: .int . - inbuf .section .text _start: # request user input movl $sys_write, %eax # service ID-number movl $stdout_ID, %ebx # device ID-number leal msg1, %ecx # message address movl len1, %edx # message length int $0x80 # enter the kernel # receive user input movl $sys_read, %eax # service ID-number movl $stdin_ID, %ebx # device ID-number leal inbuf, %ecx # buffer address movl maxin, %edx # buffer length int $0x80 # enter the kernel movl %eax, maxin # save input count # push characters onto stack leal inbuf, %esi # point ESI to buffer movl maxin, %ecx # setup ECX for count decl %ecx # but omit final byte nxch1: movb (%esi), %al # load next character pushl %eax # and push onto stack incl %esi # advance array-pointer loop nxch1 # then back for another # pop characters from stack leal inbuf, %edi # point EDI to buffer movl maxin, %ecx # setup ECX for count decl %ecx # but onlt final byte nxch2: popl %eax # pop next character movb %al, (%edi) # and store in buffer incl %edi # advance array-pointer loop nxch2 # then back for another # announce program output movl $sys_write, %eax # service ID-number movl $stdout_ID, %ebx # device ID-number leal msg2, %ecx # message address movl len2, %edx # message length int $0x80 # enter the kernel # display program output movl $sys_write, %eax # service ID-number movl $stdout_ID, %ebx # device ID-number leal inbuf, %ecx # message address movl maxin, %edx # message length int $0x80 # enter the kernel # output one blank line movl $sys_write, %eax # service ID-number movl $stdout_ID, %ebx # device ID-number leal msg3, %ecx # message address movl len3, %edx # message length int $0x80 # enter the kernel # terminate this program movl $1, %eax # service ID-number movl $0, %ebx # setup exit-code int $0x80 # enter the kernel .globl _start # visible entry-point .end # no more to assemble