[英]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.