2

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)

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
JustToKnow
  • 785
  • 6
  • 23
  • 3
    Parts can never be larger than the whole. You only have 15 numbers to check. So, each of your counters has to be able to hold the number 15 for the worst case. That's a general programming issue, not 68HC11. Just like in C you define a variable big enough to hold the result, you'll have to do the same here. What is `QUANTITY`? The number of array items you've specified is 15, not 200, so end of array would be ARRAY+15-1. When checking for end (CPX) you can use `BLO` with +15 or `BLS` with +14. Try to write some of the code yourself, and then someone can jump in and correct any mistakes. – tonypdmtr Jun 10 '20 at 23:46
  • 3
    Hey Tony, *QUANTITY* is the highest quantity of values (elements) that the array can hold. In *ARRAY* i put some random values. Do you get me?. I've written some code using the THRSim11 (do you know this program?) but it was not correct at all; i'm still green and everything seems a little "strange" (i learn a lot from answers and you explain very well!) – JustToKnow Jun 11 '20 at 00:07
  • 1
    @tonypdmtr i have updated my question; i have splitted it into 2 different parts. in the first part i want to obtain the quantity of *positive, negative or zero elements* inside a given array and in the last part i want to obtain the absolute values from a given array. Could you please help me with this two scenarios? – JustToKnow Jun 11 '20 at 05:29

1 Answers1

1

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;
}
tonypdmtr
  • 3,037
  • 2
  • 17
  • 29
  • Thank you for replying, Tony :). The THRSim11 throws an error message over this line:*#ARRAY+::ARRAY* is this syntax correct? – JustToKnow Jun 11 '20 at 23:43
  • 1
    The syntax is for ASM11 (http://aspisys.com/asm11.htm). I suppose you could change it to `#ARRAY+QUANTITY` and uncomment `QUANTITY` definition. Also, remove the `/2` in it. (I can't help with your assembler as I've never used it. Each assembler has its own quirks, and my ASM11 tops them all!) – tonypdmtr Jun 11 '20 at 23:59
  • Tony, why should i use #ARRAY+QUANTITY instead of #ARRAY+QUANTITY-1? – JustToKnow Jun 12 '20 at 02:25
  • 2
    Because of the `BLO` command that follows. If you change to `#ARRAY+QUANTITY-1` you must also change `BLO` to `BLS` – tonypdmtr Jun 12 '20 at 06:24
  • 2
    Tony, yeah..it makes sense :D. I understood that but it is not very clear to me what you did to obtain the ABSOLUTE value. you merged both cases into a single one. Could you please show me how to obtain THE SECOND PART (absolute values from a given array). -i created this thread https://stackoverflow.com/questions/62337005/assembly-language-arrays – JustToKnow Jun 12 '20 at 11:55
  • 2
    Also, how could i replace this: *::ARRAY*, idont want to use the *::* because they dont work properly on my emulator :/ – JustToKnow Jun 12 '20 at 12:02
  • We already talked about it: `#ARRAY+QUANTITY` instead of `#ARRAY+::ARRAY`, and have `QUANTITY` defined at some point. – tonypdmtr Jun 12 '20 at 21:15
  • You didn't have to make a new thread asking the same thing. To have only the absolute value, one way is to remove all `INC` instructions and related variables from my current answer. – tonypdmtr Jun 12 '20 at 21:16
  • HyTony, how are you? I made my own code in assembly but it is not working properly (i've splitted my question into 2 different threads). What's wrong? https://stackoverflow.com/questions/62494955/positive-negative-and-zero-assembly https://stackoverflow.com/questions/62494971/absolute-values-assembly – JustToKnow Jun 21 '20 at 06:09