stuck with assembly code

Discussion in 'Programmer's Corner' started by justtrying, Feb 11, 2012.

  1. justtrying

    Thread Starter Active Member

    Mar 9, 2011
    329
    349
    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...

    Code ( (Unknown Language)):
    1.          ORG     PROGRAM_ADD
    2. MAIN
    3.         LDS     #STACK_ADD
    4.         LDAB    #SIZE_ARRAY                     ;counter
    5.         LDX     #ARRAY
    6.         BSR     COUNTPOSITIVE
    7.  
    8.         SWI
    9.  
    10. COUNTPOSITIVE
    11.  
    12.  
    13.     PSHX
    14. LOOP
    15.         LDAA 0,X
    16.         BMI COUNT
    17.         STAA 1,X+
    18.         DBNE B,LOOP
    19.  
    20. COUNT
    21.     INCB
    22.     PULX
    Tnxs
     
  2. MrChips

    Moderator

    Oct 2, 2009
    12,436
    3,360
    Firstly, tell us which micro and IDE you are using. Looks like HC11 to me.
    Secondly, show the complete code listing.
     
  3. LDG

    New Member

    Feb 10, 2012
    4
    1
    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.
     
  4. justtrying

    Thread Starter Active Member

    Mar 9, 2011
    329
    349
    microcontroller is HCS12 and I am using WINIDE32.

    Code ( (Unknown Language)):
    1.  
    2. 0800    LDS    #$2000
    3. 0803    LDAB    #$04
    4. 0805    LDX    #$0901
    5. 0808    BSR    $080B
    6. 080A    SWI
    7. 080B    PSHX
    8. 080C    LDAA,X
    9. 080E    BMI    $0815
    10. 0810    STAA 1,X+
    11. 0812    DBNE B $080C
    12. 0815    INCB
    13. 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.
     
  5. MrChips

    Moderator

    Oct 2, 2009
    12,436
    3,360
    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.

    Code ( (Unknown Language)):
    1.  
    2. MAIN
    3.            :
    4.            :
    5. HERE
    6.            :
    7.            :
    8.           BRA HERE
    9.  
    If you understand this so far, next I will show you how to set up a subroutine.
    Code ( (Unknown Language)):
    1.  
    2. MAIN
    3.            :
    4.            :
    5.            :
    6.            :
    7.           STOP
    8.  
     
  6. justtrying

    Thread Starter Active Member

    Mar 9, 2011
    329
    349
    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.
     
  7. MrChips

    Moderator

    Oct 2, 2009
    12,436
    3,360
    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.

    Code ( (Unknown Language)):
    1.  
    2. MAIN
    3.              :
    4.              :
    5.             BSR COUNTPOSITIVE
    6.              :
    7.              :
    8. HANG        NOP             ;  not necessary, we do this so that we can set a breakpoint in debug
    9.             BRA HANG
    10.  
    11.  
    12. COUNTPOSITIVE
    13.              :
    14.              :
    15.             RTS
    16.  
    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: Feb 11, 2012
  8. justtrying

    Thread Starter Active Member

    Mar 9, 2011
    329
    349
    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.
     
  9. justtrying

    Thread Starter Active Member

    Mar 9, 2011
    329
    349
    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 ;(

    Code ( (Unknown Language)):
    1. ;COUNTING NEGATIVE NUMBERS
    2.  
    3. PROGRAM_ADD     EQU     $0800
    4. ARRAY_ADD       EQU     $0900
    5. STACK_ADD       EQU     $2000
    6. SIZE_ARRAY      EQU     $4
    7.  
    8.          ORG     ARRAY_ADD
    9. COUNT_POS       DS       1
    10. ARRAY           DB       $85,$73,$23,$89
    11.  
    12.         ORG     PROGRAM_ADD
    13. MAIN
    14.         LDS     #STACK_ADD
    15.         LDAB    #0004                    ;counter
    16.         LDX        #ARRAY
    17.         BSR     COUNTPOSITIVE
    18.  
    19.  
    20. COUNTPOSITIVE
    21.  
    22. LOOP1
    23.     LDAA 0,X
    24.  
    25.     INX    
    26.         BMI LOOP1
    27.  
    28. LOOP2
    29.     DECB
    30.     LDAA 0,X
    31.     INX
    32.     BMI LOOP1
    33.     DECB    
    34. DONE
    35.     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.

    Code ( (Unknown Language)):
    1. 0800    LDS    #$2000
    2. 0803    LDAB    #$04
    3. 0805    LDX    #$0901
    4. 0808    BSR    $080a
    5. 080a    LDAA    0,X
    6. 080c    INX    
    7. 080d    BMI    $080a
    8. 080f    DECB
    9. 0810    LDAA    0,X
    10. 0812    INX
    11. 0813    BMI    $080a
    12. 0815    DECB
    13. 0816    SWI
     
    Last edited: Feb 12, 2012
  10. MrChips

    Moderator

    Oct 2, 2009
    12,436
    3,360
    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.

    Code ( (Unknown Language)):
    1.  
    2.       ORG     PROGRAM_ADD
    3. MAIN        
    4.       LDS     #STACK_ADD
    5.       LDAB    #0004                      ;counter
    6.       LDX      #ARRAY        
    7.       BSR     COUNTPOSITIVE  
    8.  
    9. COUNTPOSITIVE  
    10.  
    11. LOOP1
    12.      LDAA 0,X      
    13.      INX             BMI
    14.      LOOP1
    15.  
    You are still ending the main program incorrectly. You must not allow the MCU to go from the main code into the subroutine code.
    Code ( (Unknown Language)):
    1.  
    2.       ORG     PROGRAM_ADD
    3. MAIN        
    4.       LDS     #STACK_ADD
    5.       LDAB    #0004                      ;counter
    6.       LDX      #ARRAY        
    7.       BSR     COUNTPOSITIVE  
    8.  
    9. Hang
    10.      NOP
    11.      BRA Hang
    12.  
    13. COUNTPOSITIVE  
    14.  
    15. LOOP1
    16.      LDAA 0,X      
    17.      INX             BMI
    18.      LOOP1
    19.  
    This is the reason I added the Hang code.
     
    Last edited: Feb 12, 2012
  11. MrChips

    Moderator

    Oct 2, 2009
    12,436
    3,360
    Code ( (Unknown Language)):
    1.  
    2. ; edited by Mr Chips
    3.  
    4.          ORG     PROGRAM_ADD
    5. MAIN
    6.         LDS     #STACK_ADD
    7.         LDAB    #SIZE_ARRAY                     ;counter
    8.         LDX     #ARRAY
    9.         BSR     COUNTPOSITIVE
    10.  
    11. HANG
    12.         NOP
    13.         BRA HANG
    14.        
    15.  
    16. COUNTPOSITIVE
    17.      :
    18.      :
    19.      :
    20.     RTS
    The initialization in MAIN is ok.
    You have some serious problems in the subroutine.
     
  12. MrChips

    Moderator

    Oct 2, 2009
    12,436
    3,360
    Here is what you have:
    Code ( (Unknown Language)):
    1.  
    2. COUNTPOSITIVE
    3.  
    4.     PSHX
    5. LOOP
    6.         LDAA 0,X
    7.         BMI COUNT
    8.         STAA 1,X+
    9.         DBNE B,LOOP
    10.  
    11. COUNT
    12.     INCB
    13.     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).

    Code ( (Unknown Language)):
    1.  
    2. ; This subroutine will return with A = number of positive values
    3. COUNTPOSITIVE
    4.         CLRA          ; clear the counter
    5. LOOP
    6.         TST 0,X       ; test item
    7.         BMI CONT      ; negative
    8.         INCA          ; increment the counter
    9. CONT
    10.         INX           ; point to next item
    11.         DBNE B ,LOOP  ; test if done
    12.         RTS
    13.  
    The previous edit was for negative values. This code has been corrected for counting positive values.
     
    Last edited: Feb 12, 2012
  13. justtrying

    Thread Starter Active Member

    Mar 9, 2011
    329
    349
    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 ;)
     
Loading...