简体   繁体   English

气泡分类组件(MSP430)

[英]Bubble Sort Assembly (MSP430)

So I'm having trouble dictating where I should place my swap statements in my sort function. 因此,我在确定应该在我的sort函数中放置交换语句的位置时遇到麻烦。 It works here and there but Maybe I've cmp.b/mov.b in the wrong memory address or in my line? 它在这里和那里都有效,但是也许我在错误的内存地址或我的行中输入了cmp.b / mov.b? I am using a TI MSP430 which is a 16 bit micro controller, so it doesn't have the same capabilities as some higher tier devices, so the code has to be somewhat simple. 我正在使用TI MSP430,它是一个16位微控制器,因此它不具有与某些更高层设备相同的功能,因此代码必须有点简单。

;---------------------------------------------------------------------------
; MSP430 Assembler Code Template for use with TI Code Composer Studio
;
;
;---------------------------------------------------------------------------
        .cdecls C,LIST,"msp430.h"       ; Include device header file

;---------------------------------------------------------------------------
        .def    RESET                   ; Export program entry-point to
                                        ; make it known to linker.
;---------------------------------------------------------------------------
        .text                           ; Assemble into program memory.
        .retain                         ; Override ELF conditional linking
                                        ; and retain current section.
        .retainrefs                     ; And retain any sections that have
                                        ; references to current section.

;---------------------------------------------------------------------------
ARY1        .set    0x0200          ;Memory allocation  ARY1
ARY1S       .set    0x0210          ;Memory allocation  ARYS
ARY2        .set    0x0220          ;Memory allocation  ARY2
ARY2S       .set    0x0230          ;Memory allocation  AR2S
RESET       mov.w   #__STACK_END,SP         ; Initialize stackpointer
StopWDT     mov.w   #WDTPW|WDTHOLD,&WDTCTL  ; Stop watchdog timer


;---------------------------------------------------------------------------
; Main loop here
;---------------------------------------------------------------------------
;Memory allocation of arrays must be done prior to the RESET & StopWDT

        clr R4                  ;Clear Register
        clr R5                  ;Clear Register
        clr R6                  ;Clear Register

SORT1       mov.w   #ARY1,  R4      ;Initialize R4 to point to ARY1 in the  
                                     memory
            mov.w   #ARY1S, R6      ;Initialize R6 to point to ARY1S in the 
                                     memory where the sorted ARY1 will be 
                                     stored
            call    #ArraySetup1    ;Create elements are store them in ARY1
            call    #COPY           ;Copy the elements from the ARY1 space 
                                     to ARY1S space
            call    #SORT           ;Calling Subroutine Sort with parameter 
                                     passing in R4 abd R6

SORT2       mov.w   #ARY2,  R4      ;Initialize R4 to point to ARY2  in the 
                                     memory
            mov.w   #ARY2S, R6      ;Initialize R6 to point to ARY2S in the 
                                     memory where the sorted ARY2 will be 
                                     stored
        call    #ArraySetup2    ;Create elements are store them in ARY2
        call    #COPY           ;Copy the elements from the ARY2 space to 
                                 ARY1S space
        call    #SORT           ;Calling Subroutine Sort with parameter 
                                  passing in R4 abd R6

    Mainloop    jmp Mainloop            ;loop in place for ever

;Array element initialization Subroutine
ArraySetup1 mov.b   #10,    0(R4)   ;Define the number of elements in the 
                                     array
        mov.b   #17,    1(R4)   ;store an element
        mov.b   #75,    2(R4)   ;store an element
        mov.b   #-67,   3(R4)   ;store an element
        mov.b   #23,    4(R4)   ;store an element
        mov.b   #36,    5(R4)   ;store an element
        mov.b   #-7,    6(R4)   ;store an element
        mov.b   #44,    7(R4)   ;store an element
        mov.b   #8,     8(R4)   ;store an element
        mov.b   #-74,   9(R4)   ;store an element
        mov.b   #18,    10(R4)  ;store an element
        ;store the rest of the 10 elements
        ret

;Array element initialization Subroutine
 ArraySetup2    mov.b   #10,    0(R4)   ;Define the number of elements in 
                                          the array
        mov.b   #54,    1(R4)   ;store an element
        mov.b   #-4,    2(R4)   ;store an element
        mov.b   #-23,   3(R4)   ;store an element
        mov.b   #-19,   4(R4)   ;store an element
        mov.b   #-72,   5(R4)   ;store an element
        mov.b   #-7,    6(R4)   ;store an element
        mov.b   #36,    7(R4)   ;store an element
        mov.b   #62,    8(R4)   ;store an element
        mov.b   #0,     9(R4)   ;store an element
        mov.b   #39,    10(R4)  ;store an element

        ;store the rest of the 10 elements
        ret

 ;Copy original Array to allocated Array-Sorted space
 COPY       mov.b   0(R4), R10      ;save n (number of elements) in R10
        inc.b   R10             ;increment by 1 to account for the byte n to 
                                  be copied as well
        mov.w   R4, R5          ;copy R4 to R5 so we keep R4 unchanged for 
                                 later use
        mov.w   R6, R7          ;copy R6 to R7 so we keep R6 unchanged for 
                                 later use
LP          mov.b   @R5+, 0(R7)     ;copy elements using R5/R7 as pointers
        inc.w   R7
        dec     R10
        jnz LP
        ret

;Sort the copy of Array saved in the allocated Array-Sorted space, while 
keeping original Array unchanged
;replace the following two lines with your actual sorting algorithm.
;Sort the copy of Array saved in the allocated Array-Sorted sapce, while 
keeping original Array unchanged
SORT
        clr R7
        clr R8
        clr R9
        clr R10
        clr R11
        clr R12
        clr R13
        clr R14
        clr R15
        mov.b R5, R11     ;counter
        dec R11
        mov.b @R4+, R7
        mov.b @R4, R8
        cmp.b R7,R8
  *         jz    noswap
  *         jge   No_Swap
        mov.b R7, R9
        mov.b R8, R7
        mov.b R9, R8
        inc R10
        mov.b r8, 0(r4)
        mov.b r7, -1(r4)
        dec R11
        tst R11
    *   jnz Swap
        cmp.w #0, R10 ; swap counter
     *   jnz Swap
        ret
;To bubble sort, you need to scan the array n-1 times,
;In every scan, you compare from top down each two consecutive elements, and 
you swap them if they are not in ascending order.
;Notice that in the first scan you get the largest element (no matter where 
it is in the array) pushed all the way to the bottom.
;So your next scan should be n-1 iterations, and then n-2 and so on.
;So every time you come back to the top of the array for a new scan, your n 
 (the number of comparisons) must be decremented by 1.
;In the last scan, you need only one comparison.
;Hints:
;Your sorting algorithm starts with R6 as a pointer to the array
;you need to save n (number of elements) in R8, then decrement it by 1 (n-1) 
to become the number of comparisons.
;Copy R6 to R7 so you keep R6 unchanged as it points to the top of the array 
for every new scan.
;Copy n-1 to R9 and use R9 as a loop counter, while keeping the current n-1 
value in R8 for the next scan.
;In the scan loop get an element and auto increment pointer R7, then get 
next element without changing R7.
;Compare the two elements, if not in ascending order, swap them.
;Repeat the scan from the top as pointed to by (R6), and every time 
 decrement the number of comparisons (R8).

 ;--------------------------------------------------------------------------
 ; Stack Pointer definition
 ;--------------------------------------------------------------------------
        .global __STACK_END
        .sect   .stack

 ;--------------------------------------------------------------------------
 ; Interrupt Vectors
 ;--------------------------------------------------------------------------
        .sect   ".reset"                ; MSP430 RESET Vector
        .short  RESET

most crudely simplified bubble sort loop inner body has to: 最粗略简化的气泡排序循环内部主体必须:

loop_body:
  - compare *i* and *i+1* element
  - if they are not sorted, then swap(i, i+1) elements
  - ++i
  - loop to loop_body when i+1 is still valid

Let's check what you have (I don't know msp430 asm, so I'm just guessing the instruction meaning, use instruction reference guide and debugger to verify): 让我们检查一下您拥有什么(我不知道msp430 asm,所以我只是在猜测指令的含义,请使用指令参考指南和调试器进行验证):

        mov.b R5, R11     ;counter
        dec R11

the r11 "length-1" counter is set (not checked if it was 0 or 1 before). 设置了r11 “ length-1”计数器(之前未检查它是否为0或1)。 And your code does neither set r5 to length, so there's some garbage in r5 in reality, but the idea was to have length there, I guess. 而且您的代码都没有将r5设置为length,因此实际上r5中存在一些垃圾,但是我想是要在其中具有长度。

here the main body loop starts, so this would be a good place for some loop label 从这里开始主体循环,所以这对于某些循环标签来说是个好地方

        mov.b @R4+, R7
        mov.b @R4, R8

seems as R7 = i-th element, R8 = i+1-th element, and ++i is done also 似乎是R7 =第i个元素,R8 =第i + 1个元素,并且++ i也完成了

        cmp.b R7,R8

comparing values ("if (expr)" part) 比较值(“ if(expr)”部分)

  *         jz    noswap
  *         jge   No_Swap

probably "jge" is what you want, to skip over "then" part of "if" 可能是您想要的“ jge”,跳过“ if”的“ then”部分

        mov.b R7, R9
        mov.b R8, R7
        mov.b R9, R8

Swap of values in registers... 交换寄存器中的值...

        inc R10

No idea what is this (maybe swap counter). 不知道这是什么(也许是交换计数器)。

        mov.b r8, 0(r4)
        mov.b r7, -1(r4)

Writing r8 to i+1 element, and r7 to i element (old "i" in this comment, while the r4 is already i+1 value) - this is end of "swap" of the "then" 将r8写入i + 1元素,并将r7写入i元素(此注释中的旧“ i”,而r4已经是i + 1值)-这是“ then”的“ swap”的结尾

ie after this comes the "No_Swap" label, to continue with the loop without swap 即在此之后出现“ No_Swap”标签,以继续循环而不交换

        dec R11
        tst R11
    *   jnz Swap

going through all elements of array (usually, unless the length of array was already "1" or less). 遍历数组的所有元素(通常,除非数组的长度已经为“ 1”或更小)。

        cmp.w #0, R10 ; swap counter
     *   jnz Swap

Here comes the swap counter into play, inducing another loop if some swap happened, but this is completely wrong, because you need to reset swap counter, reset array pointer r4 , and reset length counter r11 before you can enter the main loop again. 交换计数器开始起作用,如果发生某些交换,则会引起另一个循环,但这是完全错误的,因为您需要先重置交换计数器,重置数组指针r4和长度计数器r11然后才能再次进入主循环。

And for fun, try to decipher what does this code, and how it differs from yours (it's not like some complete code or fix, it's about the difference, when you will understand it, you will understand): 为了好玩,请尝试解释此代码的功能以及与您的代码有何不同(这与某些完整的代码或修复程序不同,它是关于区别的,当您理解它时,您将理解):

Bubble_loop
        mov.b  @R4+, R7
        mov.b  @R4, R8
        cmp.b  R7,R8
        jge    No_Swap
        inc    R10
        mov.b  r8, -1(r4)
        mov.b  r7, 0(r4)
No_Swap dec    R11
        jnz    Bubble_loop

And as always with assembly programming, nothing helps more to clear any doubts, than launching the code in some simulator or on machine, and use debugger to single-step over each instruction, checking the register and memory state before/after each instruction, and verifying everything works as expected. 与汇编编程一样,除了在某些模拟器中或在机器上启动代码,并使用调试器单步执行每条指令,检查每条指令之前/之后的寄存器和内存状态之外,没有什么比其他解决方案更能消除任何疑问了。验证一切正常。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM