assembly - summing positive numbers

Thread Starter

justtrying

Joined Mar 9, 2011
439
I am trying to write a subroutine that will find an average of positive numbers in an array. I am stuck on adding the numbers. The operations only seem to work with A and B registers. In this case I am not sure if I am executing addition properly. This is the best way that I came up with. Also in my branching, when I ran the program, it counted negative numbers as well, I am not sure where the problem is. (HCS12, WINIDE32)

Rich (BB code):
*          Subroutine: AvgPositive
*          Scope: count average of positive numbers using stack
*          Input parameters: Index reg X points to the array, Index reg Y holds size of array
*          Output parameters: result is returned to reg A
*          Stack is used therefore no registers are modified

AVGPOSITIVE
      
        LDX   #ARRAY
        CLRB
        LDY   #SIZE_ARRAY               ;counter to end of subroutine                           
 
LOOP3
        BRCLR 0,X,80,LOOP4                          ;branch if contents are positive
LOOP4
        LDAB    0,X
        ABA
        INX
        DBNE Y,LOOP3

        RTS

        SWI
p.s. SWI we supposed to use for reasons to be explained to us later on...

rest of the program:

Rich (BB code):
PROGRAM_ADD     EQU     $0800
ARRAY_ADD       EQU     $0900
STACK_ADD       EQU     $2000
SIZE_ARRAY      EQU     $4

         ORG     ARRAY_ADD
COUNT_POS    DS    1
AVG_POS   DS  1
ARRAY     DB       $23,$24,$86,$26


        ORG     PROGRAM_ADD
MAIN1
        LDS     #STACK_ADD
        LDAB    #SIZE_ARRAY                             ;counter
PART1
          LDX    #ARRAY
    BSR    COUNTPOSITIVE

PART2
        LDX #ARRAy
        BSR AVGPOSITIVE
 

MrChips

Joined Oct 2, 2009
30,712
Firstly, I will point out where you have errors.
In another post I will offer some solutions.

Rich (BB code):
LOOP3
        BRCLR 0,X,80,LOOP4                          ;branch if contents are positive
LOOP4
You have a number of problems here. 80 is a decimal value. To test the MSB (bit-7) you meant to use the mask $80.

Branching to LOOP4 is redundant. The next statement to be executed will be at LOOP4 if the branch is not taken, i.e. the logic flow is not correct. I will show you how to correct this later.

You are still using RTS and SWI incorrectly.
 

Thread Starter

justtrying

Joined Mar 9, 2011
439
yes, I see what you mean about the mask. I think I know what you mean about SWI, it should be at the end of main, before the subroutines.

I realize the problem with the loop, but I haven't been able to figure out how to correct it. I obviously want the program to go into the next loop only if the number it sees is positive to add them, otherwise I want it to go back to test the next number. Originally I had a next line in loop 3 testing for negative number and branching back to itself if true, but you already know that the number is negative from the other test, so I don't really know how to do.
 

MrChips

Joined Oct 2, 2009
30,712
I am not familiar with the HC12 instruction set but it has many enhanced instructions and shortcuts that help to simplify the programming.

Firstly, you have to think about overflows. If you are summing 8-bit positive values, you will need a 16-bit accumulator. You will be limited to summing a total of 256 values.
So right off the bat you will need the 16-bit D register (A:B).

Here is one solution:

Rich (BB code):
SUMPOSITIVE:

    LDX #ARRAY
    LDY #SIZE_ARRAY
    CLRA                      ; clear D register
    CLRB

LOOP:
    BRSET 0,X, $80, NEXT       ; skip if negative
    ADDD 0,X                   ; accumulate sum

NEXT:
    INX
    DBNE Y, LOOP   ; repeat

    SWI            ;return to debug
 

Thread Starter

justtrying

Joined Mar 9, 2011
439
Thank you, I had something similar yesterday in the lab, but it wasn't working because I was using A and B as counters, which of course is D. I realized today that I can use other registers as counters as well... But I couldn't see that putting ADDD inside the first loop would make such a big difference.

Greatly appreciate your patience
 
Top