//---------------------------------------------------------------- // summer.s // // This program draws a calendar-layout for summer's months. // Its purpose is to show how the data-arrays can be defined // within assembly language when showing a partial calendar. // // assemble using: $ as summer.s -o summer.o // and link using: $ ld summer.o -o summer // // programmer: ALLAN CRUSE // written on: 5 MAR 2006 //---------------------------------------------------------------- # manifest constants .equ nmonths, 3 # count of months to show .equ linelen, 24 # number of chars in line .equ listlen, 12 # number of lines in list .equ mbuflen, linelen * listlen .equ ybuflen, mbuflen * nmonths .equ sys_write, 4 .equ sys_exit, 1 .equ STDOUT, 1 .section .data ndays: .int 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 names: .ascii "JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC" line0: .ascii " " # 24 blanks line1: .ascii " ---------------------- " # 22 dashes line2: .ascii " xxx " # for month line3: .ascii " xx xx xx xx xx xx xx " # for weeks array: .long line0, line0, line1, line2, line1 .long line3, line3, line3, line3, line3, line3 .long line0 newln: .ascii "\n\n" .section .bss mm: .space 4 # month-number now nn: .space 4 # number of months ii: .space 4 # months to indent mbuf: .space mbuflen # buffer for month ybuf: .space ybuflen # buffer for year .section .text _start: #----------------- # initializations #----------------- cld # setup direction movl $5, mm # start from June movl $3, nn # do three months movl $0, ii # months done now #--------------------------------------- # outer loop: interates over the months #--------------------------------------- nxtmm: # insert the month-name in 'line2' movl $3, %ecx # chars in a month-name movl mm, %eax # current month-number mull %ecx # offset to month-name leal names(%eax), %esi # point to month-name leal line2+10, %edi # point to name-field rep movsb # copy the month-name leal names, %esi #------------------------------------- # inner loop: iterates over the lines #------------------------------------- movl $listlen, %ebp # number of array-items leal array, %ebx # address of line-array leal mbuf, %edi # address of the buffer nxitm: # copy the next line movl (%ebx), %esi # point to source movl $linelen, %ecx # length of line rep movsb # copy the line addl $4, %ebx # advance the array-index decl %ebp # decrement line-counter jnz nxitm # copy another line # now install these month-lines into the year-buffer # how far do we indent? movl $linelen, %eax # length of a line mull ii # times month now leal ybuf(%eax), %edi # where to put top line leal mbuf, %esi # where to get top line movl $12, %ebx # number of array-items nxcpy: pushl %edi movl $linelen, %ecx # number of chars to copy rep movsb # copy the line popl %edi addl $linelen, %edi addl $linelen, %edi addl $linelen, %edi decl %ebx jnz nxcpy incl mm # increment month-number incl ii # increment indent-count decl nn # decrement months-count jnz nxtmm # develop another month #----------------------------------------- # write the buffer-contents to the screen #----------------------------------------- leal ybuf, %esi # point to output-buffer movl $listlen, %ebp # count of lines in list nxrow: movl $sys_write, %eax # service-ID for 'write' movl $STDOUT, %ebx # device-ID for screen movl %esi, %ecx # where to find string movl $linelen*nmonths, %edx # length of the string int $0x80 # invoke kernel service movl $sys_write, %eax # service-ID for 'write' movl $STDOUT, %ebx # device-ID for screen leal newln, %ecx # where to find string movl $1, %edx # length of the string int $0x80 # invoke kernel service addl $linelen*nmonths, %esi # advance source-pointer decl %ebp # decrement line counter jnz nxrow # and write other lines # terminate the program movl $sys_exit, %eax # service-ID for 'exit' movl $0, %ebx # value for 'exit-code' int $0x80 # invoke kernel service .global _start # make entry-point visible .end # nothing more to assemble