0

I wrote a function in 68000 assembly that prompts the user to enter the size of a list then prompts them to enter each number and store it in the list. Function screenshot.

Now I want to write a second function to "search" through the list to find the maximum, minimum and average values of the list and store them. I know how to go about it in other languages with certain algorithms, but I can't figure out how to compare each value to find what I am looking for and just need someone to point me in the right direction.

  • 1
    [Easy68K 3 number find min,max](https://stackoverflow.com/q/58739668) shows how to find min/max of 3 numbers. You could do something similar to compare and branch on a value you loaded from the array. And/or start with C or pseudocode and translate each statement as directly as you can into assembly. Or use a C compiler to make an example loop for you; compile with optimization enabled. – Peter Cordes Oct 31 '22 at 04:17

1 Answers1

1

You already have a piece of code that walks the list (which is rather an array in your case). Some pseudo code could be

    lea.l      aX,startOfList
    clr.b      dA                ; register dA holds largest so far
    move.b     #255,dB           ; register dB holds smallest so far
    clr.B      dC                ; register dC holds running average
loop:
    cmp.b      (aX),dA           ; is current bigger than everything else?
    blt.s      noBigger          ;
    move.b     (aX),dA           ; remember current as biggest
noBigger:
    cmp.b      (aX),dB           ; is current smaller than smallest so far?
    bgt.s      noSmaller         
    move.b     (ax),dB
noSmaller:
    move.b     (aX)+,dE          ; fetch a temporary
    ext.w      dE                ; make it a word
    bsr        average           ; and build a running average

    bra loop

Note the loop counter (you already have that in your input code) is not shown here, that would be an exercise of your own. The code works by initializing the registers holding the minimum value with the maximum possible and the maximum with the minimum possible, then checking for each entry whether the current one is bigger/smaller than the biggest/smallest so far and replacing it, if yes.

tofro
  • 5,640
  • 14
  • 31
  • An average normally weights all values equally, not `a0 >> 8 + a1>>7 + a2>>6 + ...` (the first value gets divided by 2 `n` times). You need to divide by the array length once, after the loop, or use a more complicated formula if you want to do more work to compute an average for each subset of the array, not just update a total like a normal person: [Incremental averaging](https://math.stackexchange.com/q/106700) / [General - Is there a way to calculate an average based off of an existing average and given new parameters for the resulting average?](https://stackoverflow.com/q/3998780) – Peter Cordes Nov 08 '22 at 11:52
  • @PeterCordes Of course it is. But do you really think the *exact average* is the core of this question? – tofro Nov 08 '22 at 11:55
  • Small rounding errors are fine. But it's not fine if the algorithm isn't even remotely close to correct. Yours heavily weights towards the last number. e.g. mean [1,2,4,8,16,32] is 63/6 = 10.5. Your algorithm finishes with (10+32)/2 = 21 as the average, twice the correct answer, relative error of 100%. That's way beyond "not mathematically correct". – Peter Cordes Nov 08 '22 at 12:01
  • If it makes you happy, I'll remove the "average" part of the answer completely. It's absolutely not relevant for the answer. – tofro Nov 08 '22 at 12:43
  • 2
    I don't see why you're reluctant to just sum into a word register and divide after the loop. That's obviously better than an algorithm which gives very wrong answers for arrays where the final few elements aren't close to the mean. Calling a subroutine to build a running average seems insane to me. You don't need a *running* average, you just need one result when you're done. – Peter Cordes Nov 08 '22 at 12:45