-2

I'm programming an old MCU (68hc11), I'm trying to migrate from C language to assembly code using the 68hc11 instructions.

I want to write a program in assembly that counts the number of POSITIVE, NEGATIVE, and ZERO values that exist inside a given array. DO NOTE that all values inside ARRAY could be all positive or all negative or all zeros,do you get me? So I should define the size of the variables that will store the quantity properly.

NOTE: The end of the array is: ARRAY+QUANTITY-1

Array: contains some random values

QUANTITY: represent the highest number of elements that the ARRAY can hold

I wrote this program in C:

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

[...]

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

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

Now, I want to translate that but in assembly (I GOT STUCK IN HERE, i'm not getting what i want)

RWM         EQU $0
ROM         EQU   $C000
VRESET      EQU   $FFFE

QUANTITY    EQU 800 ;MEANS THE MAXIMUM AMOUNT OF VALUES THAT THE ARRAY WILL CONTAIN

            ORG RWM

POSITIVE        RMB 2
NEGATIVE        RMB 2
ZEROS           RMB 2

            ORG ROM
START:
            CLRA
            CLRB
            CLR POSITIVE
            CLR ZEROS
            CLR NEGATIVE
            LDY #ARRAY
            
LOOP
            CPY #(ARRAY+QUANTITY-1)

            BHI END
            LDD 0,Y
            INY
            BLT NEGATIVE_NUMBER
            BEQ ZERO_NUMBER
            BGE POSITIVE_NUMBER
            
            
NEGATIVE_NUMBER     INC NEGATIVE
                        BRA LOOP
                        
POSITIVE_NUMBER     INC POSITIVE
                        BRA LOOP
                        
ZERO_NUMBER         INC ZEROS
                        BRA LOOP
                        

END         BRA END

ARRAY       DW    78,554,-44,-4,2547,0,-3,0,1,7,8,

        ORG VRESET
        DW  START

What's wrong with my code?

EDIT:

ERROR

RWM         EQU $0
ROM         EQU   $C000
VRESET      EQU   $FFFE

QUANTITY    EQU 800 ;MEANS THE MAXIMUM AMOUNT OF VALUES THAT THE ARRAY WILL CONTAIN

            ORG RWM

POSITIVE        RMB 2
NEGATIVE        RMB 2
ZEROS           RMB 2

            ORG ROM
START:
            CLRA
            CLRB
            CLR POSITIVE
            CLR ZEROS
            CLR NEGATIVE
            LDY #(ARRAY-2)
            
LOOP
             INY
         INY
             CPY #(ARRAY+2*QUANTITY-1)
         BHI END
         LDD 0,Y
         BLT NEGATIVE_NUMBER
                 BEQ ZERO_NUMBER
                 BGE POSITIVE_NUMBER
            
            
NEGATIVE_NUMBER     INC NEGATIVE
                        BRA LOOP
                        
POSITIVE_NUMBER     INC POSITIVE
                        BRA LOOP
                        
ZERO_NUMBER         INC ZEROS
                        BRA LOOP
                        

END         BRA END

ARRAY       DW    78,554,-44,-4,2547,0,-3,0,1,7,8,

        ORG VRESET
        DW  START

I got this output (not sure about it)

inage

JustToKnow
  • 785
  • 6
  • 23
  • 1
    What does "not getting what i want" mean? The things that jump out as wrong are that you're incrementing your address by 1 each time through the loop - but the array elements are 2 bytes long; and you're looping over 800 addresses, even though only the first few of those have defined contents. – jasonharper Jun 21 '20 at 06:12
  • Hint: you can simplify the branching by computing one of the quantities from the other 2. e.g. count negative and zero, and calculate after the loop `positive = quantity - neg - zero` – Peter Cordes Jun 21 '20 at 06:16
  • Hey @jasonharper ,thank you for replying. I mean, i'm running my code and it is not doing what i want; i'm kinda lost (not an expert) – JustToKnow Jun 21 '20 at 06:22

1 Answers1

2

What's wrong with my code?

I only had a quick look at your program, so my answer may be wrong:

LDD 0,Y

Obviously you are operating with 16 bit numbers. Otherwise you would use LDA or LDB instead of LDD.

CPY #(ARRAY+QUANTITY-1)

This would be correct if QUANTITY is the size of the array in bytes (e.g. 30 in the case of int A[15]).

If QUANTITY is the number of elements and you are operating with 16-bit numbers, you have to multiply with two:

CPY #(ARRAY+2*QUANTITY-1)
INY

Once again this would work for 8-bit elements. For 16-bit elements you have to add two to each element or to increment Y twice:

INY
INY
INY
BLT NEGATIVE_NUMBER

The INY instruction will modify the zero flag and therefore influence the BLT, BGE and BEQ instructions. You cannot use INY between LDD and the branch instructions.

BLT ...
BEQ ...
BGE ...

Not really an error, but the BGE instruction will always branch. You may place the POSITIVE_NUMBER number code after the BEQ instruction and remove the BGE instruction.

EDIT

I'm not understanding this part: INY followed by Bxx

I was thinking about three different ways to do this. The simplest one seems to be:

    LDY #(ARRAY-2)  ; Because we'll do INY twice right now
LOOP
    INY
    INY
    CPY #(ARRAY+2*QUANTITY-1)
    BHI END
    LDD 0,Y
    BLT NEGATIVE_NUMBER
    ...
Martin Rosenau
  • 17,897
  • 3
  • 19
  • 38
  • Hey Martin, thank you for replying.I'm not understanding this part: INY BLT NEGATIVE_NUMBER, not really sure how to solve that. – JustToKnow Jun 21 '20 at 15:56
  • Martin, i feel a little dumb in this part: what would it be the big difference between *LDY #ARRAY* and *LDY #(ARRAY-2)* – JustToKnow Jun 21 '20 at 16:21
  • Dude, i've updated my question; after running your code i got some syntax errors. – JustToKnow Jun 21 '20 at 16:37
  • @Student_new Does `ARRAY+QUANTITY-1` work? If yes, the assembler might not support multiplication; try `ARRAY+QUANTITY+QUANTITY-1` instead of `ARRAY+2*QUANTITY-1`. – Martin Rosenau Jun 21 '20 at 18:52
  • It is working now but not sure about what i'm getting (i've updated my question) – JustToKnow Jun 21 '20 at 19:30
  • 1
    After `LDD` use `BPL` for positive, `BEQ` for zero, `BMI` for negative. Although, once you have tested two of them, the third is implied and can fall-through to the respective `INC` without an explicit branch instruction. @Student_new Some assemblers may complain about forward references. So, define your array before (higher up the file) you refer to it. – tonypdmtr Jun 21 '20 at 20:16
  • Hey Tony, how is it goin'?. i modified my code according to your comment (https://imgur.com/a/QQzqk96). I'm getting this output, something does not make sense to me: https://imgur.com/a/86ID2uG – JustToKnow Jun 21 '20 at 20:34
  • @Student_new I assume by that you mean the results don't match your array (the negative in particular). Check the assembler listing for `CPY #(ARRAY+2*QUANTITY-1)` instruction. Does it actually compare against the expected value? Some assemblers (like my ASM11) process expressions left to right (i.e. no multiplication precedence), such that the expression evaluates to ((ARRAY+2)*QUANTITY)-1 making your code run over a completely different set of values than you expect. Also, your counters should by byte sized for this example. – tonypdmtr Jun 22 '20 at 13:20
  • @Student_new It will be more helpful to show listing so that one can check the actual code generated (e.g., I can only guess what `QUANTITY` you have defined. Is it 11 or something else?) – tonypdmtr Jun 22 '20 at 13:24