Skip to main content
edited tags
Link
michael.zech
  • 4.5k
  • 8
  • 33
  • 56
Source Link
michael.zech
  • 4.5k
  • 8
  • 33
  • 56

Assembly program which detects all numbers with two integral divisors

For an FASM assembly course I've to do the following exercise:

"Write a program that takes the number n as input. Then it prints all the numbers x below n that have exactly 2 different integral divisors (Besides 1 and x).

For example: 15 is such a number. It is divisible by 1,3,5,15. (Here 3 and 5 are the two different divisiors, besides 1 and 15).

However, 4 is not such a number. It is divisible by 1,2,4."

Full description can be seen here: GitHub xorpd.

Here's the code I've written:

format PE console
entry start

include 'win32a.inc' 

; ===========================================
; Write a program that takes the number n as
; input. Then prints all the numbers x below
; n that have exactly 2 different intergral 
; divisors (Besides 1 and x).
; Example: 15 : 1, 3, 5, 15 => 3 and 5.
; ===========================================

; ------ Usage example ----------------------
; The first "f" is the number n which was entered by the user.

; C:\Users\michael\Desktop\fasmProgs>divisors
; f
; 6
; 8
; a
; e
; f 
; ------------------------------------------

section '.text' code readable executable

start:
    call    read_hex            ; Provided by teacher. Reads in a hexadecimal number from stdin.
    
    mov     edi,    eax         ; edi becomes the upper limit.
    mov     esi,    5           ; esi becomes the control variable.

outerLoop:
    inc     esi
    mov     ebx,    2           ; ebx becomes the divisor and control variable of the inner loop.
    mov     ecx,    0           ; Counts how many division have been possible.
innerLoop:
    xor     edx,    edx
    mov     eax,    esi
    div     ebx

    cmp     edx,    0
    jne     prepareInnerIteration
    inc     ecx
    
prepareInnerIteration:
    inc     ebx                  ; Increment the divisor.

    cmp     ebx,    esi          ; Here the control variable acts as the upper limit.
    jl      innerLoop

prepareOuterIteration:
    cmp     ecx,    2
    jne     goToNextIteration

    cmp     esi,    6            ; In case no number was given. Just a blank.
    je      goToNextIteration

    mov     eax,    esi
    call    print_eax            ; Provided by teacher. Prints eax to stdin.    

goToNextIteration:
    cmp     esi,    edi
    jl      outerLoop

    push    0
    call    [ExitProcess]

include 'training.inc'

On of the tests I've done:

Testing with decimal 30 (hexadecimal 1e) as n.

I enter hexadecimal 1e (decimal 30).

It returns:

  • 6 => Can be divided by 2 and 3. Therefore correct detected.

  • 8 => 2, 4

  • 10 => 2, 5

  • 14 => 2, 7

  • 15 => 3, 5

  • 21 => 3, 7

  • 22 => 2, 11

  • 26 => 2, 13

  • 27 => 3, 9

I would say it works. At least essentially.

Nevertheless: There might be flaws even bugs in my program. And I guess one could improve it a lot.

So therefore:

Any hints, comments and recommendation by more experienced Assembly programmer very much appreciated.