//---------------------------------------------------------------- // leapyear.s // // This program determines whether or not a year, specified // by the user as a command-line argument, is a "leap-year" // in case it occurs in the 21st Century (i.e., 2001-2099). // // assemble using: $ as leapyear.s -o leapyear.o // and link using: $ ld leapyear.o base10io.o -o leapyear // // programmer: ALLAN CRUSE // written on: 28 FEB 2006 //---------------------------------------------------------------- # manifest constangts .equ sys_write, 4 .equ sys_exit, 1 .equ STDOUT, 1 .equ STDERR, 2 .section .data year: .int 2006 # default-value for year msg0: .ascii "your year falls outside the 21st century\n" len0: .int . - msg0 msg1: .ascii "xxxx is a leap year\n" len1: .int . - msg1 msg2: .ascii "xxxx is not a leap year\n" len2: .int . - msg2 .section .text _start: # check for presence of command-line argument cmpl $1, (%esp) # argument is missing? je argok # yes, use our default # convert command-line digit-string to a number movl 8(%esp), %esi # point to digit-string call asc2eax # coinvert ascii to int movl %eax, year # save number as 'year' # verify year falls in the 21st century cmpl $2001, year # year preceeds 2001? jb not21 # yes, year not valid cmpl $2099,year # year follows 2099? ja not21 # yes, year not valid argok: # insert year into both message-strings movl year, %eax # setup year in EAX leal msg1, %edi # point EDI to message 1 call eax2asc # convert number to ascii leal msg2, %edi # point EDI to message 2 call eax2asc # convert number to ascii # now see if year is divisible by 4 movl year, %eax # setup our dividend xorl %edx, %edx # dividend zero-endended movl $4, %ecx # setup our divisor divl %ecx # perform the division # select message to display based on the remainder-value cmp $0, %edx # remainder is zero? je isleap # yes, show message #1 jmp noleap # else show message #2 isleap: # display message 1 movl $sys_write, %eax # service-ID for 'write' movl $STDOUT, %ebx # device-ID for output leal msg1, %ecx # message address movl len1, %edx # message length int $0x80 # invoke kernel service jmp exit # terminate program noleap: # display message 2 movl $sys_write, %eax # service-ID for 'write' movl $STDOUT, %ebx # device-ID for output leal msg2, %ecx # message address movl len2, %edx # message length int $0x80 # invoke kernel service jmp exit # terminate program not21: # show error-message and quit movl $sys_write, %eax # service-ID for 'write' movl $STDERR, %ebx # device-ID for errors leal msg0, %ecx # message address movl len0, %edx # message length int $0x80 # invoke kernel service exit: # terminate this program movl $sys_exit, %eax # service-ID for 'exit' movl $0, %ebx # setup return-code int $0x80 # invoke kernel service .global _start .end