assembly68hc11

Counting number (HC11)


I'm still playing with this MC

Now i want to count positive/negative numbers and 0's in a given array. In c, i did something like this and it worked perfectly:

int A[15], pos, neg, nul, i;

[...]

pos = 0;
neg = 0;
nul = 0;

for for (i = 0; i < 15; i++) {
    if (A[i] > 0) {
        pos++;
    }
    if (A[i] < 0) {
        neg++;
    }
    if (A[i] == 0) {
        nul++;
    }
}

So, the next step is to make something similar but in assembly code, i was thinking about this:

RWM         EQU   $0
ROM         EQU   $C000
RESET       EQU   $FFFE

QUANTITY    EQU   200

            ORG RWM

POSITIVES       RMB 
NEGATIVES       RMB 
ZEROS           RMB 

            ORG ROM
Main:

END         BRA END

ARRAY       DW    1,4,8,-87,0,0,1,4,5,8,7,4,4,1,-9

        ORG RESET
        DW  Main

i'm a little confused right here because i would need to consider the worst cases, i mean: all are positive, or all negative or all zero. So, i should define variable sizes according to the information to be saved. I think the end of the array should be ARRAY + QUANTITY-1.

EDIT#1:

For this case i would like to obtain this output:

Since th ARRAY contains these elements:

1,4,8,-87,0,0,1,4,5,8,7,4,4,1,-9

I should get this output:

POSITIVES       11  
NEGATIVES       2   
ZEROS           2

But remember:

i must consider the worst cases, i.e: all are positive, or all negative or all zero


Another different case:

Suppose that i want to obtain the absolute values of all the elements that are stored in a specific array.

I can achieve that using 'C',i mean, i could perform something like this:

#include <stdio.h>
#include <math.h>

int absolute(int *array, int N);

int main()
{
    int array[16] = {0,1,2,3,-4,5,6,7,-8,9,-10,11,12,13,14,20};
    int ray[16];
    int i;

                for ( i = 0; i < 16; i++ )
        ray[i]=absolute(array,16);
        printf("the absolute value is %d\n", ray[i]);

    return 0;
}

int absolute(int *array, int N)
{
    int i;

    for(i=0; i<N; i++)
        if (array[i]<0)
            array[i] = array[i] * (-1);

}

I tried to do that in assembly (using 68hc11 instructions)

RWM      EQU        $0
ROM      EQU     $C000
RESET    EQU     $FFFE

         ORG    RWM
ABSOLUTE RMB    

        ORG     ROM
Start:      


END     BRA END

ARRAY   DW   4,144,447,-14,-555,-1147

        ORG RESET
        DW  Start

I want to store inside ABSOLUTE all the absolute elements from ARRAY

PS: i have not defined the size for ABSOLUTE

I would like to see these values inside ABSOLUTE:

4,144,447,14,555,1147 (UNSIGNED NUMBERS)


Solution

  • The definition of QUANTITY as 200 seems pointless in your example because you hard code your array so it has a known number of elements regardless of what QUANTITY says. It would be better to have the assembler define QUANTITY to the actual number of elements like shown below (but not used in my ASM11 based example).

    RAM                 equ       $0
    ROM                 equ       $C000
    Vreset              equ       $FFFE
    
    ;*******************************************************************************
                        #ROM
    ;*******************************************************************************
                        org       ROM
    
    ARRAY               dw        4,144,447,-14,-555,-1147
    ;QUANTITY           equ       *-ARRAY/2
    
    ;*******************************************************************************
                        #RAM
    ;*******************************************************************************
                        org       RAM
    
    absolute            rmb       ::ARRAY
    zeros               rmb       1
    positives           rmb       1
    negatives           rmb       1
    
    ;*******************************************************************************
                        #ROM
    ;*******************************************************************************
    
    Start               ldx       #ARRAY              ;X -> source
                        ldy       #absolute           ;Y -> destination
              ;-------------------------------------- ;initialize all counters to zero
                        clr       zeros
                        clr       positives
                        clr       negatives
              ;--------------------------------------
    Loop                ldd       ,x                  ;D = word to test
                        beq       CountZero           ;go count zero
                        bpl       CountPositive       ;go count positive number
              ;--------------------------------------
                        inc       negatives           ;count negative number
    ;                   negd                          ;make it positive (abs)
                        coma
                        comb
                        addd      #1
                        bra       Cont
              ;--------------------------------------
    CountZero           inc       zeros
                        bra       Cont
              ;--------------------------------------
    CountPositive       inc       positives
    ;                   bra       Cont
              ;--------------------------------------
    Cont                std       ,y                  ;save absolute value
                        ldab      #2                  ;B = word size
                        abx                           ;X -> next word
                        aby                           ;Y -> next word
                        cpx       #ARRAY+::ARRAY      ;check for end of array
                        blo       Loop                ;repeat for all elements
    
                        bra       *
    
                        org       Vreset
                        dw        Start
    

    BTW, your C code is incorrect. I think you meant to write something like this:

    #include <stdio.h>
    
    #define SIZE 16
    
    int absolute(int array[], int ray[], int N)
    {
      for (int i=0; i<N; i++)
        ray[i] = array[i] * (array[i]<0?-1:1);
    }
    
    int main()
    {
      int array[SIZE] = {0,1,2,3,-4,5,6,7,-8,9,-10,11,12,13,14,20};
      int ray[SIZE];
    
      absolute(array,ray,SIZE);
      for (int i = 0; i < SIZE; i++ )
        printf("The absolute value of %3i is %3i\n", array[i],ray[i]);
      return 0;
    }