//---------------------------------------------------------------- // factors.s // // This program uses the MUL and DIV instructions, and gets // its input via a command-line argument typed by the user. // // programmer: ALLAN CRUSE // written on: 26 SEP 2003 // revised on: 15 FEB 2005 -- to address stack using %esp //---------------------------------------------------------------- .section .data n: .int 0 i: .int 0 ten: .int 10 errmsg: .string "A command-line argument is required" report: .string "\nThe factors of %d are shown below: \n" outnum: .string " %d " nxline: .string "\n" .section .text main: # check for a command-line argument cmpl $1, 4(%esp) # is argc > 1 ? jg argok # yes, continue # if none, print an error-message and exit pushl $errmsg call printf addl $4, %esp jmp finis # convert argument from a digit-string to a number argok: movl 8(%esp), %ebx # get argv movl 4(%ebx), %esi # get argv[1] movl $0, n # initial n # conversion: add next digit-value to ten times n nxdgt: movb (%esi), %al # get next digit incl %esi # advance pointer cmpb $'0', %al # below '0'? jb inval # yes, not a digit cmpb $'9', %al # above '9'? ja inval # yes, not a digit andl $0xF, %eax # convert ascii to number xchgl %eax, n # xchange with prior n mull ten # multiply n by ten addl %eax, n # add to digit-value jmp nxdgt # check for another digit inval: # print explanatory message, showing user's value for n pushl n pushl $report call printf addl $8, %esp # while-loop: to check for all possible factors of n movl $1, i # initialize i while: movl i, %eax # get current i cmpl %eax, n # check: i <= n ? jl finis # no, then exit # see if integer i divides n without any remainder movl n, %eax xorl %edx, %edx divl i orl %edx, %edx jnz notf # show this factor of n pushl i pushl $outnum call printf addl $8, %esp notf: # increment the "trial" factor incl i jmp while finis: # print a newline and exit pushl $nxline call printf addl $4, %esp ret .globl main .end assemble-and-link using: $ gcc factors.s -o factors