//---------------------------------------------------------------- // showpi.s // // This program employs Pentium floating-point instructions // to exhibit the value of 'PI' to sixteen decimal-places. // // assemble using: $ as showpi.s -o showpi.o // and link using: $ ld showpi.o -o showpi // // programmer: ALLAN CRUSE // written on: 04 DEC 2003 //---------------------------------------------------------------- # manifest constants .equ sys_EXIT, 1 .equ sys_WRITE, 4 .equ STDOUT, 1 .data TenTo16: .quad 10000000000000000 # to shift decimal-point pivalue: .tfloat 0 # holds a ten-byte value message: .ascii "\n\t\t\tPI = " # text explaining output numbuff: .ascii " " # buffer holds numerals .ascii "\n\n" # appends an extra line msgsize: .int . - message # length of the message .text _start: # compute PI * 10**16 and store its integer part finit # initialize coprocessor fldpi # load the value of 'PI' fildq TenTo16 # load 10**16 multiplier fmulp %st, %st(1) # to shift decimal-point fbstp pivalue # store it as packed BCD fwait # wait for NPX to finish # convert packed-decimal integer to an ascii string call bcd2ascii # routine for conversion # display a message that shows the value for 'PI' movl $sys_WRITE, %eax # service id-number movl $STDOUT, %ebx # device id-number leal message, %ecx # message address movl msgsize, %edx # message length int $0x80 # enter the kernel # return control to the Linux shell movl $sys_EXIT, %eax # service id-number xorl %ebx, %ebx # program exit-code int $0x80 # enter the kernel #------------------------------------------------------------------ bcd2ascii: # # This procedure converts a packed-decimal stored as 'pivalue' # to its representation as a string of decimal numerals with a # decimal-point inserted just before the final sixteen digits. # (The stack is used here to reverse the order of the digits.) # leal pivalue, %esi # point ESI to BCD number leal numbuff, %edi # point EDI to out buffer cld # use forward processing # loop to unpack digits and convert to ascii codes movl $9, %ecx # nine digit-pairs to unpack nxunpk: lodsb # fetch next packed-BCD byte xorb %ah, %ah # clear accumulator hi-byte rorw $4, %ax # rotate hi-nybble into AL rorb $4, %ah # rotate lo-nybble into AH addw $0x3030, %ax # convert nybbles to ascii pushl %eax # save numeral-pair on stack loop nxunpk # again for remaining bytes # loop to recover pairs and output in reverse order movl $9, %ecx # count of pairs to recover nxpair: popl %eax # recover saved numeral-pair stosw # move both to output buffer loop nxpair # again for remaining pairs # fixup output by inserting a decimal-point just ahead of # the final sixteen places in eighteen-character string movb $'.', %al # setup decimal-point in AL xchgb %al, numbuff+1 # exchange AL with 2nd byte movb %al, numbuff+0 # then put AL into 1st byte ret # back to calling procedure #------------------------------------------------------------------ .globl _start # make entry visible