Calculating Divisors with Q8

This next problem gets a little more mathy, diving into the middle of a real algorithm, finding divisors of a given value. As a limitation of the program, it can produce bad data if i * j > 255. Q8 can only handle values from 0-255, and will overflow if pushed past that maximum. With that in mind, let's dig into our program!

One of the things put in place here is a bit of an early exit to dramatically shorten run time. The check to see if i < j ensures that the code doesn't run past the halfway point and print duplicate divisors. Without the early exit, the code would print 1 12 2 6 3 4 4 3 6 2 12 1, which is a giant waste of time and effort.

One of the things this program doesn't do, is sort the divisor list. That remains as a bonus challenge for the reader. You'll notice that it doesn't need a full sort. Half the values are ascending, and the other half the values are descending. with a little clever array walking code, you could collate the two, only walking the list once or twice.

C-like Program

int input_value = 12;
int candidate = 0;
for (int i = 0; i <= input_value; i++) {
    // J-LOOP
    for (int j = 0; j <= input_value; j++) {
        candidate += i;
        if (candidate == input_value) {
            if (i > j) {
                // EXIT
            } else {
                // add i, j to divisor array
    candidate = 0;

Bytecode Program

Assembly Program

; I typically jump into real code at the beginning
; like this to give myself scratch-room if I forget
; something, or need a little more space

JMP i-loop ; Hop into actual code

LOAD A i ; Read in i
LOAD B in ; Read in input_value
CMP A B ; Check to see if the loop has finished
JE exit ; goto exit if done
INC A ; i++
STORE A i ; store i
JMP j-loop

LOAD A j ; Read in j
LOAD B in ; Read in input_value
CMP A B ; Check to see if loop has finished
JE j-loop_reset
INC A ; j++
STORE A j ; store j
JMP get_next_candidate ; goto get next candidate

; reset j and candiate to 0
STORE A j ; set j to 0
STORE A candidate ; set candiate to 0
JMP i-loop

LOAD A candidate ; read in candidate
LOAD B i ; read in i
ADD A B ; candidate += i
STORE A candidate ; store new candiate
LOAD B in ; load input_value
CMP A B ; candidate == input_value?
JE append_list
JMP j-loop

LOAD A i ; read in i
LOAD B j ; read in j
CMP A B ; i > j?
JG exit
STOREI A idx ; store i to array[n]
STOREI B idx+ ; store j to array[n+1]
LOAD A idx ; load n
LOAD B idx+ ; load n+1
INC A ; n += 2
INC B ; (n+1) += 2
STORE A idx ; store new n
STORE B idx+ ; store new n+1
JMP j-loop


idx: $224
idx+: $225
in: $12
i: $0
j: $0
candidate: $0