The   proper divisors   of a positive integer N are those numbers, other than N itself, that divide N without remainder.

For N > 1 they will always include 1,   but for N == 1 there are no proper divisors.



Examples

The proper divisors of     6     are   1, 2, and 3.

The proper divisors of   100   are   1, 2, 4, 5, 10, 20, 25, and 50.



Task

 Create a routine to generate all the proper divisors of a number.
 use it to show the proper divisors of the numbers 1 to 10 inclusive.
 Find a number in the range 1 to 20,000 with the most proper divisors. Show the number and just the count of how many proper divisors it has.


Show all output here.



Related tasks

   Amicable pairs
   Abundant, deficient and perfect number classifications
   Aliquot sequence classifications
   Factors of an integer
   Prime decomposition


 
/* ARM assembly Raspberry PI  */
/*  program proFactor.s   */
 
/* REMARK 1 : this program use routines in a include file 
   see task Include a file language arm assembly 
   for the routine affichageMess conversion10 
   see at end of this program the instruction include */
/*******************************************/
/* Constantes                              */
/*******************************************/
.equ STDOUT, 1                           @ Linux output console
.equ EXIT,   1                           @ Linux syscall
.equ WRITE,  4                           @ Linux syscall
 
/*******************************************/
/* Initialized data                        */
/*******************************************/
.data
szMessStartPgm:          .asciz "Program start \n"
szMessEndPgm:            .asciz "Program normal end.\n"
szMessError:             .asciz "\033[31mError Allocation !!!\n"
szCarriageReturn:        .asciz "\n"
 
/* datas message display */
szMessEntete:            .ascii "Number :"
sNumber:                 .space 12,' '
                         .asciz " Divisors :"
szMessResult:            .ascii " "
sValue:                  .space 12,' '
                         .asciz ""
szMessDivNumber:         .ascii "\nnumber divisors :"
sCounter:                .space 12,' '
                         .asciz "\n"
szMessNumberMax:         .ascii "Number :"
sNumberMax:              .space 12,' '
                         .ascii " has "
sDivMax:                 .space 12, ' '
                         .asciz " divisors\n"
/*******************************************/
/* UnInitialized data                      */
/*******************************************/
.bss 
/*******************************************/
/*  code section                           */
/*******************************************/
.text
.global main 
main:                               @ program start
    ldr r0,iAdrszMessStartPgm       @ display start message
    bl affichageMess
    mov r2,#1
1:
    mov r0,r2                       @  number
    ldr r1,iAdrsNumber              @ and convert ascii string
    bl conversion10
    ldr r0,iAdrszMessEntete         @ display result message
    bl affichageMess
    mov r0,r2                       @  number
    mov r1,#1                       @ display flag
    bl divisors                     @ display divisors
    ldr r1,iAdrsCounter              @ and convert ascii string
    bl conversion10
    ldr r0,iAdrszMessDivNumber      @ display result message
    bl affichageMess
    add r2,r2,#1
    cmp r2,#10
    ble 1b
 
    mov r2,#2
    mov r3,#0
    mov r4,#0
    ldr r5,iMaxi
2:
    mov r0,r2
    mov r1,#0                       @ display flag
    bl divisors                     @ display divisors
    cmp r0,r3
    movgt r3,r0
    movgt r4,r2
    add r2,r2,#1
    cmp r2,r5
    ble 2b
    mov r0,r4
    ldr r1,iAdrsNumberMax           @ and convert ascii string
    bl conversion10
    mov r0,r3
    ldr r1,iAdrsDivMax              @ and convert ascii string
    bl conversion10
    ldr r0,iAdrszMessNumberMax
    bl affichageMess
 
 
    ldr r0,iAdrszMessEndPgm         @ display end message
    bl affichageMess
    b 100f
99:                                 @ display error message 
    ldr r0,iAdrszMessError
    bl affichageMess
100:                                @ standard end of the program
    mov r0, #0                      @ return code
    mov r7, #EXIT                   @ request to exit program
    svc 0                           @ perform system call
iAdrszMessStartPgm:        .int szMessStartPgm
iAdrszMessEndPgm:          .int szMessEndPgm
iAdrszMessError:           .int szMessError
iAdrszCarriageReturn:      .int szCarriageReturn
iAdrszMessResult:          .int szMessResult
iAdrsValue:                .int sValue
iAdrszMessDivNumber:       .int szMessDivNumber
iAdrsCounter:              .int sCounter
iAdrszMessEntete:          .int szMessEntete
iAdrsNumber:               .int sNumber
iAdrszMessNumberMax:       .int szMessNumberMax
iAdrsDivMax:               .int sDivMax
iAdrsNumberMax:            .int sNumberMax
iMaxi:                     .int 20000
/******************************************************************/
/*     divisors function                         */ 
/******************************************************************/
/* r0 contains the number  */
/* r1 contains display flag (<>0: display, 0: no display )
/* r0 return divisors number */
divisors:
    push {r1-r8,lr}             @ save  registers 
    cmp r0,#1                   @ = 1 ?
    movle r0,#0
    ble 100f
    mov r7,r0
    mov r8,r1
    cmp r8,#0
    beq 1f
    mov r0,#1                   @ first divisor = 1
    ldr r1,iAdrsValue           @ and convert ascii string
    bl conversion10
    ldr r0,iAdrszMessResult     @ display result message
    bl affichageMess
1:                              @ begin loop
    lsr r4,r7,#1                @ Maxi
    mov r6,r4                   @ first divisor
    mov r5,#1                   @ Counter divisors
2:
    mov r0,r7                   @ dividende = number
    mov r1,r6                   @ divisor
    bl division
    cmp r3,#0                   @ remainder = 0 ?
    bne 3f
    add r5,r5,#1                @ increment counter
    cmp r8,#0                   @ display divisor ?
    beq 3f
    mov r0,r2                   @ divisor
    ldr r1,iAdrsValue           @ and convert ascii string
    bl conversion10
    ldr r0,iAdrszMessResult     @ display result message
    bl affichageMess
3:
    sub r6,r6,#1                @ decrement divisor
    cmp r6,#2                   @ End ?
    bge 2b                      @ no loop
    mov r0,r5                   @ return divisors number
 
100:
    pop {r1-r8,lr}              @ restaur registers
    bx lr                       @ return
 
/***************************************************/
/*      ROUTINES INCLUDE                 */
/***************************************************/
.include "../affichage.inc"
 