# stuck with assembly code

#### justtrying

Joined Mar 9, 2011
428
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
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
19,912
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.

#### justtrying

Joined Mar 9, 2011
428
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
19,912
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

#### justtrying

Joined Mar 9, 2011
428
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
19,912
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:

#### justtrying

Joined Mar 9, 2011
428
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 )

Much appreciated.

#### justtrying

Joined Mar 9, 2011
428
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

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

MAIN
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
19,912
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
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
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
19,912
Rich (BB code):
; edited by Mr Chips

MAIN
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
19,912
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: