//---------------------------------------------------------------- // dayout.s // // This program tests a function named 'dayout' which writes // a pair of characters to the memory-location whose address // is found in register EDI. If the value in register AL is // zero, the characters both are blanks; otherwise, a string // of one or two decimal numerals is written that represents // the numeric value in AL (modulo 31), and right-justified. // // assemble using: $ dayout.s -o dayout.o // and link using: $ dayout.o -o dayout // // programmer: ALLAN CRUSE // written on: 01 APR 2006 //---------------------------------------------------------------- .section .text #----------------------------------------------------------------- ten: .byte 10 # decimal system radix #----------------------------------------------------------------- dayout: # replaces AX by its remainder modulo 32, then writes the # (nonzero) result as a right-justified two-digit decimal # or writes two blanks if the result was equal to zero and $0x001F, %ax # isolate low 5-bits divb ten # divide by base 10 or $0x2020, %ax # set bit 5 in AH,AL test $0x0F0F, %ax # AH,AL both zeros? jz nochg # output two blanks or $0x3000, %ax # set bit 4 in AH test $0x000F, %ax # AL is zero? jz nochg # yes, one numeral or $0x0030, %ax # set bit 4 in AL nochg: mov %ax, (%edi) # output AL and AH ret # return to caller #----------------------------------------------------------------- .section .data #----------------------------------------------------------------- mdays: .int 31 # count of month's days start: .int 6 # weekday month starts dname: .space 42 # array of days' names msg: .ascii "\n" # begin message string .ascii "--------------------\n" buf: .ascii "xx xx xx xx xx xx xx\n" .ascii "xx xx xx xx xx xx xx\n" .ascii "xx xx xx xx xx xx xx\n" .ascii "xx xx xx xx xx xx xx\n" .ascii "xx xx xx xx xx xx xx\n" .ascii "xx xx xx xx xx xx xx\n" .ascii "--------------------\n" .ascii "\n" # end of message string len: .int . - msg # message string length #----------------------------------------------------------------- .section .text #----------------------------------------------------------------- _start: # clear the 'dname' array xor %edi, %edi # initialize array-index mov $42, %ecx # count of array entries nxzero: movb $0, dname(%edi) # store zero into array inc %edi # increment array-index loop nxzero # again if other entries # initialize the 'dname' array mov $0, %al # day-name starts at 0 xor %edi, %edi # day-posn starts at 0 mov mdays, %ecx # setup count with sum add start, %ecx # of mdays and start nxnam: cmp %edi, start # index preceeds start? ja noinc # yes, keep day-name 0 inc %al # else add 1 to day-name noinc: mov %al, dname(%edi) # store current day-name inc %edi # increment array-index loop nxnam # again for other days # format the buffer with valid day-names (or blanks) lea buf, %edi # point to output buffer xor %esi, %esi # initialize array-index mov $42, %ecx # count of buffer entries nxday: mov dname(%esi), %al # fetch current day-name call dayout # store day-name as chars inc %esi # increment array-index add $3, %edi # advance buffer-pointer loop nxday # again for other days # display the formatted message mov $4, %eax # service-ID for 'write' mov $1, %ebx # device-ID for screen lea msg, %ecx # message's address mov len, %edx # message's length int $0x80 # invoke kernel service # now terminate this program mov $1, %eax # service-ID for 'exit' mov $0, %ebx # value of exit-code int $0x80 # invoke kernel service #----------------------------------------------------------------- .global _start # make entry-point visible .end # nothing more to assemble