assembly - summing positive numbers

Discussion in 'Programmer's Corner' started by justtrying, Feb 18, 2012.

  1. justtrying

    Thread Starter Active Member

    Mar 9, 2011
    329
    343
    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)

    Code ( (Unknown Language)):
    1. *          Subroutine: AvgPositive
    2. *          Scope: count average of positive numbers using stack
    3. *          Input parameters: Index reg X points to the array, Index reg Y holds size of array
    4. *          Output parameters: result is returned to reg A
    5. *          Stack is used therefore no registers are modified
    6.  
    7. AVGPOSITIVE
    8.      
    9.         LDX   #ARRAY
    10.         CLRB
    11.         LDY   #SIZE_ARRAY               ;counter to end of subroutine                          
    12.  
    13. LOOP3
    14.         BRCLR 0,X,80,LOOP4                          ;branch if contents are positive
    15. LOOP4
    16.         LDAB    0,X
    17.         ABA
    18.         INX
    19.         DBNE Y,LOOP3
    20.  
    21.         RTS
    22.  
    23.         SWI
    24.  
    p.s. SWI we supposed to use for reasons to be explained to us later on...

    rest of the program:

    Code ( (Unknown Language)):
    1.  
    2. PROGRAM_ADD     EQU     $0800
    3. ARRAY_ADD       EQU     $0900
    4. STACK_ADD       EQU     $2000
    5. SIZE_ARRAY      EQU     $4
    6.  
    7.          ORG     ARRAY_ADD
    8. COUNT_POS    DS    1
    9. AVG_POS   DS  1
    10. ARRAY     DB       $23,$24,$86,$26
    11.  
    12.  
    13.         ORG     PROGRAM_ADD
    14. MAIN1
    15.         LDS     #STACK_ADD
    16.         LDAB    #SIZE_ARRAY                             ;counter
    17. PART1
    18.           LDX    #ARRAY
    19.     BSR    COUNTPOSITIVE
    20.  
    21. PART2
    22.         LDX #ARRAy
    23.         BSR AVGPOSITIVE
     
  2. MrChips

    Moderator

    Oct 2, 2009
    12,421
    3,357
    Firstly, I will point out where you have errors.
    In another post I will offer some solutions.

    Code ( (Unknown Language)):
    1.  
    2. LOOP3
    3.         BRCLR 0,X,80,LOOP4                          ;branch if contents are positive
    4. LOOP4
    5.  
    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.
     
  3. justtrying

    Thread Starter Active Member

    Mar 9, 2011
    329
    343
    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.
     
  4. MrChips

    Moderator

    Oct 2, 2009
    12,421
    3,357
    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:

    Code ( (Unknown Language)):
    1.  
    2. SUMPOSITIVE:
    3.  
    4.     LDX #ARRAY
    5.     LDY #SIZE_ARRAY
    6.     CLRA                      ; clear D register
    7.     CLRB
    8.  
    9. LOOP:
    10.     BRSET 0,X, $80, NEXT       ; skip if negative
    11.     ADDD 0,X                   ; accumulate sum
    12.  
    13. NEXT:
    14.     INX
    15.     DBNE Y, LOOP   ; repeat
    16.  
    17.     SWI            ;return to debug
    18.  
    19.  
    20.  
     
  5. justtrying

    Thread Starter Active Member

    Mar 9, 2011
    329
    343
    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
     
Loading...