汇编语言shell排序?

时间:2015-11-17 03:13:18

标签: sorting assembly arm keil

我一直在做ARM汇编语言程序,现在已接近尾声。 但是,需要将来自C的shell排序程序转换为我的代码,以便最后一部分完成,但我不太明白这一部分。所以我想在这里发布我的代码,并请你们在 ARM汇编语言

中获得有关shell排序的一些指导

对我的代码的任何建议都表示赞赏。

    AREA ShellSort, CODE, READONLY

destinationArray EQU 0x40000000

    ENTRY

    LDR    r1,=sourceArray
    LDR    r0,=destinationArray
    MOV     r2, #0              ; pointer to the original
    MOV     r3, #0              ; pointer to the destination array
    MOV     r4, #19             ; loop counter (20 elemenets so 0-19 counts as 18)
    MOV     r5, #1              ; size of copyArray

    LDR     r3, [r1], #1        ; copy element
    STR     r3, [r0]    

    BL     copyArray
    LDR    r0,=sourceArray
    MOV    r1,#arraySize
    BL     shellSort

stop    B         stop


val
    SUB    r3,#1              ;Address of source array passed in R0
    LDR    r3, [r0], #1       ;Address of destination array passed in R1
    LDR    r0, =destinationArray                      ;Number of array elements pass



copyArray

    STR r3, [r0]
    ADD     r5, #1
    MOV     r6, r5
    CMP     r4, #0
    BNE     val
    MOV PC,LR    ;Return to calling subroutine      

shellSort

    MOV PC,LR  ;Return to calling subroutine


arraySize       EQU 20
sourceArray     DCD -9,23,-100,675,2,98,13,-4,1000,23,5,234,45,67,12,-2,54,2,17,99

    END                                                                 

1 个答案:

答案 0 :(得分:0)

我的环境与您的环境不同。我重做了你的代码以适应我的测试系统。我搜索了一个好的手臂组件排序,但没有找到任何。冒泡排序适用于短期种类。我发现'Linux qsort'非常好,并已将其插入您的程序中。我的更改是小写的,您可以重新调整它以适应您的环境。

.data

.equ arraySize, 20

sourceArray:
    .word   -9,23,-100,675,2,98,13,-4,1000,23,5,234,45,67,12,-2,54,2,17,99

.equ numbytes, (arraySize * 4)
destinationArray:       @ Memory is 1 byte and an integer is 4 bytes
    .skip  numbytes     @   (1 word) on my Raspbian Jessie RPi3,
                        @   adjust for your environment.
.balign 4
format:
    .asciz " %4d  %4d  %4d  %4d  %4d  %4d  %4d  %4d  %4d  %4d\n"

.balign 4
fmt:
    .asciz "\n"

.text

.global main
main:
@   ENTRY

    push    {r4-r10, lr}        @ save registers and return value
    LDR     r1, =sourceArray
    LDR     r0, =destinationArray
    MOV     r2, #0              @ pointer to the original
    MOV     r3, #0              @ pointer to the destination array
    MOV     r4, #19             @ loop counter (20 elemenets so 0-19 counts as 18)
    MOV     r5, #1              @ size of copyArray

@   LDR     r3, [r1], #1        @ copy element
@   STR     r3, [r0]    

    BL     copyArray
    LDR    r0, =sourceArray
@   MOV    r1, #arraySize
    ldr    r1, =arraySize
    BL     shellSort

stop:
@   B      stop
    mov    r0,  #0
    pop    {r4-r10, lr}        @ restore registers and return to caller
    bx     lr


val:
    SUB    r3,#1              @Address of source array passed in R0
    LDR    r3, [r0], #1       @Address of destination array passed in R1
    LDR    r0, =destinationArray          @Number of array elements pass



copyArray:
    ldr     r3, [r1], #4      @ index source, int takes 4 bytes
@   STR     r3, [r0]
    str     r3, [r0], #4      @ index destination
    ADD     r5, #1
    MOV     r6, r5
    subs    r4, #1            @ counter--
    bgt     copyArray         @ continue copying array
@   CMP     r4, #0
@   BNE     val
    MOV     PC, LR    @Return to calling subroutine      

shellSort:

@   MOV     PC,LR  @Return to calling subroutine


@ arraySize       EQU 20
@ sourceArray     DCD -9,23,-100,675,2,98,13,-4,1000,23,5,234,45,67,12,-2,54,2,17,99

@   END                                                                 

@ ---- All below this line is added for qsort (not shellsort) ----

@ http://www.tutorialspoint.com/c_standard_library/c_function_qsort.htm
@
@ http://man7.org/linux/man-pages/man3/qsort.3.html
@
@ void qsort(void *base, size_t nmemb, size_t size,
@            int (*compar)(const void *, const void *));
@
@      qsort(r0 =array, r1 =numelements, r2 = 4 bytes,
@            r0=(r3 =cmpfunc){ r0=[r0] - r1=[r1] })

qsort_setup:
    push  {r0-r12, lr}            @ save environment
    ldr   r0,  =destinationArray  @ sorting destinationArray
    ldr   r1,  =arraySize         @ size of array elements
    mov   r2,  #4                 @ size of integer
    ldr   r3,  =cmpfunc           @ compare function for int
    bl    qsort                   @ Linux OS build in sort 

    b     print_sourceArray

cmpfunc:                          @ This work per specs above
    ldr   r0,  [r0]
    ldr   r1,  [r1]
    sub   r0,  r0, r1
    mov   pc,  lr

print_sourceArray:
    ldr   r0,  =fmt
    bl    printf
    ldr   r0,  =sourceArray
    bl    prt_half_array
    ldr   r0,  =sourceArray
    ldr   r1,  =numbytes
    add   r0,  r1, lsr #1
    bl    prt_half_array


print_destinationArray:
    ldr   r0,  =fmt
    bl    printf
    ldr   r0,  =destinationArray
    bl    prt_half_array
    ldr   r0,  =destinationArray
    ldr   r1,  =numbytes
    add   r0,  r1, lsr #1
    bl    prt_half_array
    ldr   r0,  =fmt
    bl    printf

    pop   {r0-r12, lr}            @ restore enviroment
    mov   pc, lr                  @ return

prt_half_array:
    push  {r0, lr}
    ldm   r0,  {r1-r10}
    ldr   r0,  =format
    push  {r4-r10}
    bl    printf
    add   sp,  #28
    pop   {r0, pc}
.end