【问题标题】:Bubble Sort Assembly (MSP430)冒泡排序组件 (MSP430)
【发布时间】:2018-08-06 14:40:58
【问题描述】:

所以我在指定我应该在我的排序函数中放置交换语句的位置时遇到了麻烦。它可以在这里和那里工作,但也许我的 cmp.b/mov.b 在错误的内存地址或我的行中?我使用的是 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

【问题讨论】:

    标签: arrays assembly bubble-sort msp430


    【解决方案1】:

    最粗略简化的冒泡排序循环内部必须:

    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
    

    我们来看看你有什么(我不知道msp430 asm,所以我只是猜测指令含义,使用指令参考指南和调试器来验证):

            mov.b R5, R11     ;counter
            dec R11
    

    r11 "length-1" 计数器已设置(不检查之前是 0 还是 1)。而且您的代码既没有将r5 设置为长度,所以实际上r5 中有一些垃圾,但我猜我的想法是在那里有长度。

    主体循环从这里开始,所以这将是一些循环标签的好地方

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

    似乎 R7 = i-th 元素,R8 = i+1-th 元素,并且 ++i 也完成了

            cmp.b R7,R8
    

    比较值(“if (expr)”部分)

      *         jz    noswap
      *         jge   No_Swap
    

    可能“jge”是你想要的,跳过“if”的“then”部分

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

    寄存器中的值交换...

            inc R10
    

    不知道这是什么(可能是交换计数器)。

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

    将 r8 写入 i+1 元素,将 r7 写入 i 元素(此注释中的旧“i”,而 r4 已经是 i+1 值) - 这是“then”的“swap”结束

    即之后是“No_Swap”标签,继续循环而不进行交换

            dec R11
            tst R11
        *   jnz Swap
    

    遍历数组的所有元素(通常,除非数组的长度已经是“1”或更小)。

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

    此时交换计数器开始发挥作用,如果发生交换,则会引发另一个循环,但这是完全错误的,因为您需要先重置交换计数器,重置数组指针r4,然后重置长度计数器r11再次进入主循环。

    为了好玩,试着解读一下这段代码的作用,以及它与你的有何不同(它不像一些完整的代码或修复,它是关于差异的,当你理解它时,你就会明白):

    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
    

    与汇编编程一样,没有什么比在某些模拟器或机器上启动代码更能帮助消除任何疑虑了,然后使用调试器单步执行每条指令,在每条指令之前/之后检查寄存器和内存状态说明,并验证一切按预期工作。

    【讨论】:

    • 如果您在没有发生交换的外循环迭代之后省略了提前停止,则 BubbleSort 会明显更简单。
    • @PeterCordes 是的,我也没有涵盖完整外循环处理所需的修复,也没有阅读/验证隐藏在代码 cmets 中的要求,这个答案确实侧重于 “我应该在我的排序函数中放置交换语句的位置” - 即内部循环体,仅此而已,忽略了将整个代码固定到 OP 的乐趣,毕竟拿走所有东西是自私的从中获得乐趣,只是展示完整的源代码工作(我也不打算在接下来的 5 分钟内学习 MSP430 asm + 安装一些模拟器来验证我做了什么)。 :) 但是,是的,OP 应该首先修复更简单的变体。
    • 是的,我也不知道 MSP430。 IMO,实现 BubbleSort 的唯一原因是代码量小/易于实现,如果您省略了 asm 中的提前签出,这主要是正确的。如果您关心简单 O(n^2) 排序的性能,请使用 InsertionSort;写起来不是特别难。
    猜你喜欢
    • 2016-02-10
    • 1970-01-01
    • 2013-09-28
    • 1970-01-01
    • 2013-10-09
    • 2015-09-12
    • 1970-01-01
    • 2014-06-20
    相关资源
    最近更新 更多