stuck with assembly code

Thread Starter

justtrying

Joined Mar 9, 2011
439
This is my first try to write assembly code. I need to implement a code (using stack) that would determine how many negative numbers are in a give array. Currently what I have does not even come close to doing it (I am trying to go in small chunks), and among many things that I do not understand is why when I run the simulator, instead of executing PULX, the code does BGND. Is there something wrong in how I am doing the addressing?

What I am was trying to do is implement a loop that would look at each number in the array and implement a counter. I am getting lost in push/pull and branches...

Rich (BB code):
         ORG     PROGRAM_ADD
MAIN
        LDS     #STACK_ADD
        LDAB    #SIZE_ARRAY                     ;counter
        LDX     #ARRAY
        BSR     COUNTPOSITIVE

        SWI

COUNTPOSITIVE


    PSHX
LOOP
        LDAA 0,X
        BMI COUNT
        STAA 1,X+
        DBNE B,LOOP

COUNT
    INCB
    PULX
Tnxs
 

MrChips

Joined Oct 2, 2009
30,712
Firstly, tell us which micro and IDE you are using. Looks like HC11 to me.
Secondly, show the complete code listing.
 

LDG

Joined Feb 10, 2012
4
look at each byte in the array, if bit 7 is set, a 1, then the value of the byte is
negative. -1 to -127

count bytes that have bit 7 set.
 

Thread Starter

justtrying

Joined Mar 9, 2011
439
microcontroller is HCS12 and I am using WINIDE32.

Rich (BB code):
0800    LDS    #$2000
0803    LDAB    #$04
0805    LDX    #$0901
0808    BSR    $080B
080A    SWI
080B    PSHX
080C    LDAA,X
080E    BMI    $0815
0810    STAA 1,X+
0812    DBNE B $080C
0815    INCB
0816    PULX
I'm trying to count negative numbers by using the BMI which will set N if number is negative. I don't think I am implementing the branching correctly. My problem with programming is that I have an idea of how to implement the thing, but get completely lost in the code. If I can work with someone step by step, maybe I can get a better start.
 

MrChips

Joined Oct 2, 2009
30,712
Ok, let's start with some basics.
You don't need to use SWI.
You don't need to use PSHX and PULX for now unless you know exactly what and why you are doing it.

A MAIN program will either loop for ever or come to termination with a STOP or HALT instruction.
In an embedded system, there is usually no STOP or HALT. The program is always running unless it crashes.

Rich (BB code):
MAIN
           :
           :
HERE
           :
           : 
          BRA HERE
If you understand this so far, next I will show you how to set up a subroutine.
Rich (BB code):
MAIN
           :
           :
           :
           : 
          STOP
 

Thread Starter

justtrying

Joined Mar 9, 2011
439
I could write it if I didn't have to use those... we are learning about the stack and subroutines. So I'm just going to write out the "program flow":

1. before calling the subroutine the main program initializes CPU registers with the parameters needed by the subroutine
2. main program calls the subroutine
3. subroutine is executed, upon completion, result is returned to one of the CPU registers
4. main program looks up the returned result in the register and saves it in a designated memory location

I think I've been able to do step 1. And come up with a name for the subroutine (countpositive). The stack is used here because ? - well there is another subroutine to be added afterwords, so maybe to keep track of the flow, I really do not know.

SWI is an interrupt, right? we haven't really discussed it. The learning process is mostly attempting to modify programs that are given to us, not very efficient if don't know what you are doing to begin with.
 

MrChips

Joined Oct 2, 2009
30,712
I don't know how the IDE handles the SWI instruction so I would just avoid it for now.
Let's not use PSHX and PULX for now until we understand how to use them.

All subroutines will end with an RTS instruction. So here is the construct for a main program and one subroutine.

Rich (BB code):
MAIN
             :
             :
            BSR COUNTPOSITIVE
             :
             :
HANG        NOP             ;  not necessary, we do this so that we can set a breakpoint in debug
            BRA HANG


COUNTPOSITIVE
             :
             :
            RTS
What is wrong with your code in the original post is the simulator executes the final PULX and then has nowhere else to go, so it returns to your debugger. On a real target MCU your program runs into never-never land and crashes.

There are many things wrong in your COUNTPOSITIVE subroutine which I will point out next.
 
Last edited:

Thread Starter

justtrying

Joined Mar 9, 2011
439
Thanks, I will try the subroutines and see how it works out and will post more a little later. Hopefully I can get to push/pull with your help. (got a test coming up soon :eek:)

Much appreciated.
 

Thread Starter

justtrying

Joined Mar 9, 2011
439
Trying to wrap my head around this. Here is what I have so far (still need to figure out the stack): p.s. this is using free download of miniIDE as the other one does not run on my laptop ;(

Rich (BB code):
;COUNTING NEGATIVE NUMBERS

PROGRAM_ADD     EQU     $0800
ARRAY_ADD       EQU     $0900
STACK_ADD       EQU     $2000
SIZE_ARRAY      EQU     $4

         ORG     ARRAY_ADD
COUNT_POS       DS       1
ARRAY           DB       $85,$73,$23,$89

        ORG     PROGRAM_ADD
MAIN
        LDS     #STACK_ADD
        LDAB    #0004                    ;counter
        LDX        #ARRAY
        BSR     COUNTPOSITIVE


COUNTPOSITIVE

LOOP1
    LDAA 0,X

    INX    
        BMI LOOP1

LOOP2
    DECB
    LDAA 0,X
    INX
    BMI LOOP1
    DECB    
DONE
    SWI
Ok, I think I got it to count negative numbers. Not sure how to get it to count positive numbers at the moment.

Also, the program does not stop once the array is finished. I am not sure how to get it to stop from moving into the uninitialized area. It just keeps going in the loop.

Finally, for the stack, I am not sure how push/pull will work inside the loop.

Rich (BB code):
0800    LDS    #$2000
0803    LDAB    #$04
0805    LDX    #$0901
0808    BSR    $080a
080a    LDAA    0,X
080c    INX    
080d    BMI    $080a
080f    DECB
0810    LDAA    0,X
0812    INX
0813    BMI    $080a
0815    DECB
0816    SWI
 
Last edited:

MrChips

Joined Oct 2, 2009
30,712
When I said complete code listing I meant the rest of the code. Originally I thought you were posting just a snippet of the complete program. No need to post the assembler listing.

Rich (BB code):
      ORG     PROGRAM_ADD 
MAIN         
      LDS     #STACK_ADD
      LDAB    #0004                      ;counter 
      LDX      #ARRAY         
      BSR     COUNTPOSITIVE  

COUNTPOSITIVE  

LOOP1
     LDAA 0,X      
     INX             BMI 
     LOOP1
You are still ending the main program incorrectly. You must not allow the MCU to go from the main code into the subroutine code.
Rich (BB code):
      ORG     PROGRAM_ADD 
MAIN         
      LDS     #STACK_ADD
      LDAB    #0004                      ;counter 
      LDX      #ARRAY         
      BSR     COUNTPOSITIVE  

Hang
     NOP
     BRA Hang

COUNTPOSITIVE  

LOOP1
     LDAA 0,X      
     INX             BMI 
     LOOP1
This is the reason I added the Hang code.
 
Last edited:

MrChips

Joined Oct 2, 2009
30,712
Rich (BB code):
; edited by Mr Chips

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

HANG
        NOP
        BRA HANG
        

COUNTPOSITIVE
     :
     :
     :
    RTS
The initialization in MAIN is ok.
You have some serious problems in the subroutine.
 

MrChips

Joined Oct 2, 2009
30,712
Here is what you have:
Rich (BB code):
COUNTPOSITIVE

    PSHX
LOOP
        LDAA 0,X
        BMI COUNT
        STAA 1,X+
        DBNE B,LOOP

COUNT
    INCB
    PULX
I would remove the PSHX and PULX. The RTS at the end is absolutely essential.
There is no need to STA anything to memory.
The HCS12 MCU has many enhanced instructions not commonly seen in prior MCUs.
As a shortcut, you can TST a memory location directly (a feature of Freescale's MCU architecture).

Rich (BB code):
; This subroutine will return with A = number of positive values
COUNTPOSITIVE
        CLRA          ; clear the counter
LOOP
        TST 0,X       ; test item
        BMI CONT      ; negative
        INCA          ; increment the counter
CONT
        INX           ; point to next item
        DBNE B ,LOOP  ; test if done
        RTS
The previous edit was for negative values. This code has been corrected for counting positive values.
 
Last edited:

Thread Starter

justtrying

Joined Mar 9, 2011
439
thank you, I think I understand a bit more about the flow of this. Especially appreciate that you pointed out importance of RTS, I would have never seen it. I think I am getting somewhere, hopefully.... have to leave push/pull for later, might be back with it on wednesday ;)
 
Top