我正在为Basys 3 Microblaze的汇编语言编写一个程序。然而,这种语言与我在网上能找到的任何东西都大不相同。I have documentation for it here,从第4章(第65页)开始,我可以使用汇编命令。
我的代码需要从终端输入10个字符,每次输入后它会检查Basys上的开关并更改7段显示。但我不担心这个。我遇到麻烦的部分是这10个单字符输入存储在一个数组中。我需要遍历并对这个字符数组进行冒泡排序,然后再把它们吐出来。我有一个排序函数,应该这样做,但我只是不能让它工作。如果有人能帮我弄清楚我做错了什么,我将不胜感激。我整晚都在想办法。我使用Vivado 2019.1中的Xilinx SDK(以及以下版本,因为SDK在2019.2中被删除)。
下面是我的代码:
#Equates
.set NUMLOOPS, 10
.set SWITCH_DATA, 0x40000000
.set SEV_SEG_DATA, 0x40010000
.set UART, 0x40600000
#Memory Section
$msgBegin:
.asciz "\r\n Program Start.\r\n"
.text
.align 2
$msgWithChar:
.asciz "Character %d - %c\r\n"
.text
.align 2
$Nums:
.fill 10, 4, 65
.data
.align 4
$msgLoop:
.asciz "\r\n Embedded Systems Loop #%2d.\r\n"
.text
.align 2
$msgEnd:
.asciz "\r\n Program Stop.\r\n"
.text
.align 2
$msgTest1:
.asciz "\r\n Test 1."
.text
.align 2
$msgTest2:
.asciz "\r\n Test 2."
.text
.align 2
$msgTest3:
.asciz "\r\n Test 3."
.text
.align 2
$msgSpace:
.asciz "\r\n"
.text
.align 2
#Main Program
.globl main
main:
addi r5, r0, $msgBegin # Store string to print
addi r1, r1, -4 # Push r15 onto stack
swi r15,r1, 0
brlid r15,xil_printf # Call print func; retn addr in r15
nop # Unfilled delay slot
lwi r15,r1, 0 # Pop r15 off the stack
addi r1, r1, 4
addi r19, r0, NUMLOOPS # Initialize R19 to NUMLOOPS
addi r20, r0, 1 # Initialize R20 to one
addi r22, r0, 0 # Initialize R22 to 0
.globl loop
loop:
beqi r19, sort # If R19==0, branch to done; stop program
nop
rsub r19,r20,r19 # Decrement loop counter (R19) by 1 (R20)
lwi r11, r0, SWITCH_DATA # Read data from switches
swi r11, r0, SEV_SEG_DATA # Write switch data to 7-segment disp
addi r5, r0, UART # Set R5 arg to UART memory address
addi r1, r1, -4 # Push r15 onto stack
swi r15, r1, 0
brlid r15, XUartLite_RecvByte # Call UART Receive function
nop
lwi r15, r1, 0 # Pop r15 off stack
addi r1, r1, 4
swi r3, r22, $Nums # Store value into $Nums array at offset R22
add r6, r0, r3 # Move char R3 into R6 to display to UART
addi r1, r1, -4 # Push r15 on stack
swi r15, r1, 0
brlid r15, XUartLite_SendByte # Call Uart Send function
nop
lwi r15, r1, 0 # Pop r15 off stack
addi r1, r1, 4
addi r22, r22, 4 # Increment R22 by 4 bytes
bri loop
nop
.globl sort
sort:
addi r23, r0, 10 # Initialize R23 for outer loop counter
addi r24, r0, 10 # Initialize R24 for inner loop counter
addi r22, r0, 0 # Reinitialize R22 to zero
addi r29, r0, 0 # Initialize R29 for address offset of a[0]
for1:
#Print Test
addi r5, r0, $msgTest1 # Store string to print
addi r1, r1, -4 # Push r15 onto stack
swi r15,r1, 0
brlid r15,xil_printf # Call print func; retn addr in r15
nop # Unfilled delay slot
lwi r15,r1, 0 # Pop r15 off the stack
addi r1, r1, 4
beqid r23, disp # If R23==0, branch to disp
nop
addi r23, r23, -1 # Decrement outer loop counter (R23) by 1
addi r24, r0, 10 # Initialize R24 for inner loop counter
addi r24, r24, -1 # Subtract 1 from R24 (since we are comparing i and i+1)
for2:
#Print Test
addi r5, r0, $msgTest2 # Store string to print
addi r1, r1, -4 # Push r15 onto stack
swi r15,r1, 0
brlid r15,xil_printf # Call print func; retn addr in r15
nop # Unfilled delay slot
lwi r15,r1, 0 # Pop r15 off the stack
addi r1, r1, 4
beqid r24, for1 # If R24==0, branch to for1
nop
addi r24, r24, -1 # Decrement inner loop counter (R24) by 1
addi r25, r0, 0 # Initialize R25 for address offset of a[i]
muli r25, r24, 4 # Calculate address offset for a[i]
lwi r26, r25, $Nums # Load a[i] into R26
addi r25, r25, 4 # Increment R25 for address offset of a[i+1]
lwi r27, r25, $Nums # Load a[i+1] into R27
addi r28, r0, 0
cmp r28, r26, r27
bgtid r28, for2 # If a[i] > a[i+1], skip the swap
nop
swap:
#Print Test
addi r5, r0, $msgTest3 # Store string to print
addi r1, r1, -4 # Push r15 onto stack
swi r15,r1, 0
brlid r15,xil_printf # Call print func; retn addr in r15
nop # Unfilled delay slot
lwi r15,r1, 0 # Pop r15 off the stack
addi r1, r1, 4
swi r26, r25, $Nums # Store R26 (a[i]) into a[i+1] location
swi r27, r25, $Nums # Store R27 (a[i+1]) into a[i] location (using R25 - ARRAY_OFFSET)
rsubi r25, r25, -4
bri for2
nop
.globl disp
disp:
addi r19, r0, NUMLOOPS # Reinitialize R19 to NUMLOOPS
addi r22, r0, 0 # Reinitialize R22 to zero
addi r5, r0, $msgSpace # 1st arg R5 is format string
add r6, r0, r22 # 2nd arg R6 is address offset
lwi r7, r22, $Nums # 3rd arg R7 is array value at this offset
addi r1, r1, -4 # Push r15 on stack
swi r15, r1, 0
brlid r15, xil_printf # Call printf
nop
lwi r15, r1, 0 # Pop r15 off stack
addi r1, r1, 4
.globl loop2
loop2:
beqi r19, done # If R19==0, branch to done; stop program
nop
rsub r19,r20,r19 # Decrement loop counter (R19) by 1 (R20)
addi r5, r0, $msgWithChar # 1st arg R5 is format string
add r6, r0, r22 # 2nd arg R6 is address offset
lwi r7, r22, $Nums # 3rd arg R7 is array value at this offset
addi r1, r1, -4 # Push r15 on stack
swi r15, r1, 0
brlid r15, xil_printf # Call printf
nop
lwi r15, r1, 0 # Pop r15 off stack
addi r1, r1, 4
addi r22, r22, 4 # Increment R22 by 4 bytes
bri loop2
.globl done
done:
addi r5, r0, $msgEnd # Store string to print
addi r1, r1, -4 # Push r15 onto stack
swi r15,r1, 0
brlid r15,xil_printf # Call print func; retn addr in r15
nop # Unfilled delay slot
lwi r15,r1, 0 # Pop r15 off the stack
addi r1, r1, 4
1条答案
按热度按时间jgzswidk1#
应变为
beqi r19, done
不交换值。两家商店都在同一个地址。
当前,您的代码正在处理外层循环的 * 每次 * 迭代的 * 所有 * 数组元素。在BubbleSort中,你应该在外部循环的每次迭代中减少1个元素。最大/最小值(取决于升序/降序)将移动(“冒泡”)到一个极端,你应该不再需要处理它。
因为你冒泡到数组的 * 开头 *(多么奇怪......),只要内部循环运行一次,它将是你不再需要考虑的第一个元素。
如果删除以下内容,编写正确的代码会更容易:
一种可能的解决方案