Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sorting 在Arm组件中实现选择排序时遇到的问题_Sorting_Assembly_Arm_Selection Sort - Fatal编程技术网

Sorting 在Arm组件中实现选择排序时遇到的问题

Sorting 在Arm组件中实现选择排序时遇到的问题,sorting,assembly,arm,selection-sort,Sorting,Assembly,Arm,Selection Sort,所以我的程序有问题。它应该在文本文件中读取 每行都有一个数字。然后将其存储在数组中,使用选择排序对其进行排序,然后将其输出到新文件。文件的读写工作非常好,但我的排序代码工作不正常。当我运行程序时,它似乎只存储了一些数字 在数组中,然后是一堆零 如果我的输入是112323,32,12,19,2,1,23。输出为0,0,0,0,2,1,23。我很确定问题在于如何从阵列中存储和加载 因为假设该部分工作,我找不到选择排序算法不工作的任何原因 好的,多亏了您的帮助,我发现我需要更改加载和存储指令,以便它与

所以我的程序有问题。它应该在文本文件中读取 每行都有一个数字。然后将其存储在数组中,使用选择排序对其进行排序,然后将其输出到新文件。文件的读写工作非常好,但我的排序代码工作不正常。当我运行程序时,它似乎只存储了一些数字 在数组中,然后是一堆零

如果我的输入是112323,32,12,19,2,1,23。输出为0,0,0,0,2,1,23。我很确定问题在于如何从阵列中存储和加载 因为假设该部分工作,我找不到选择排序算法不工作的任何原因

好的,多亏了您的帮助,我发现我需要更改加载和存储指令,以便它与所使用的说明符(ldr->ldrb和str->strb)匹配。但是我需要做一个32位数字的排序算法,那么说明符和加载/存储指令的哪种组合允许我这样做呢?或者我必须一次加载/存储8位吗?如果是这样,我该怎么做

.data

.balign 4
        readfile: .asciz "myfile.txt"


.balign 4
        readmode: .asciz "r"


.balign 4
        writefile: .asciz "output.txt"


.balign 4
        writemode: .asciz "w"

.balign 4
        return: .word 0


.balign 4
        scanformat: .asciz "%d"


.balign 4
        printformat: .asciz "%d\n"


.balign 4
        a: .space 32


.text
.global main
.global fopen
.global fprintf
.global fclose
.global fscanf
.global printf

main:
        ldr r1, =return
        str lr, [r1]
        ldr r0, =readfile
        ldr r1, =readmode
        bl fopen
        mov r4, r0
        mov r5, #0
        ldr r6, =a
loop:
        cmp r5, #7
        beq sort
        mov r0, r4
        ldr r1, =scanformat
        mov r2, r6
        bl fscanf
        add r5, r5, #1
        add r6, r6, #1
        b loop



sort:
    mov r5,#0  /*array parser for first loop*/
    mov r6, #0  /* #stores index of minimum*/
    mov r7, #0 /* #temp*/
    mov r8, #0 /*# array parser for second loop*/
    mov r9, #7 /*# stores length of array*/
    ldr r10, =a /*# the array*/
    mov r11, #0 /*#used to obtain offset for min*/
    mov r12, #0 /*# used to obtain offset for second parser access*/


loop3:
    cmp r5, r9 /*# check if first parser reached end of array*/
    beq write /* #if it did array is sorted write it to file*/
    mov r6, r5 /*#set the min index to the current position*/
    mov r8, r6 /*#set the second parser to where first parser is at*/
    b loop4 /*#start looking for min in this subarray*/

loop4:
    cmp r8, r9 /* #if reached end of list min is found*/
    beq increment /* #get out of this loop and increment 1st parser**/
    lsl  r7, r6, #3 /*multiplies min index by 8 */
    ADD r7, r10, r7 /* adds offset to r10 address storing it in r7 */
    ldr r11,  [r7] /* loads value of min in r11 */
    lsl r7, r8, #3 /* multiplies second parse index by 8 */
    ADD r7, r10, r7 /* adds offset to r10 address storing in r7 */
    ldr r12, [r7]  /*  loads value of second parse into r12 */
    cmp r11, r12 /* #compare current min to the current position of 2nd parser !!!!!*/
    movgt r6, r8 /*# set new min to current position of second parser */
    add r8, r8, #1 /*increment second parser*/

    b loop4 /*repeat */
    
    
increment:
    lsl r11, r5, #3 /* multiplies first parse index by 8 */
    ADD r11, r10, r11 /* adds offset to r10 address stored in r11*/
    ldr r8, [r11] /* loads value in memory address in r11 to r8*/
    lsl r12, r6, #3 /*multiplies min index by 8   */
    ADD r12, r10, r12 /*ads offset to r10 address stored in r12 */
    ldr r7, [r12] /* loads value in memory address in r12 to r7 */

    str r8, [r12] /* # stores value of first parser where min was !!!!!*/
    str r7, [r11] /*# store value of min where first parser was !!!!!*/
    add r5, r5, #1 /*#increment the first parser*/

    ldr r0,=printformat
    mov r1, r7
    bl printf
    b loop3 /*#go to loop1*/


write:
        mov r0, r4
        bl fclose
        ldr r0, =writefile
        ldr r1, =writemode
        bl fopen
        mov r4, r0
        mov r5, #0
        ldr r6, =a


loop2:
        cmp r5, #7
        beq end
        mov r0, r4
        ldr r1, =printformat
        ldrb r2, [r6]
        bl fprintf
        add r5, r5, #1
        add r6, r6, #1
        b loop2


end:
        mov r0, r4
        bl fclose
        ldr r0, =a
        ldr r0, [r0]
        ldr lr, =return
        ldr lr, [lr]
        bx lr

我发现我需要更改加载和存储指令 使其与所使用的说明符匹配(ldr->ldrb和str->strb)。 但是我需要做一个32位数字的排序算法 那么说明符和加载/存储指令的哪种组合会 允许我这么做吗

如果要从内存中读取32b(4字节)值,首先必须在内存中有4个字节的值。这并不奇怪:)

例如,如果您的输入是数字
1
2
3
4
,则每个数字的值比内存中的值高32b

0x00000000: 01 00 00 00 | 02 00 00 00  <- 32b values of 1 & 2
0x00000008: 03 00 00 00 | 04 00 00 00  <- 32b values of 3 & 4
因此,通过ldrb
ldrb
阅读8bit会得到数字1、2、3、4

但是
ldr
确实可以从内存中读取32b值(一次读取所有4个字节),并且可以在寄存器中获得32b值
0x04030201



注意:little endian系统的示例您是否尝试在调试器中单步执行代码?此外,ARM具有类似于
[r10、r6、lsl#3]
的寻址模式,这对于索引64位元素的数组非常有用。一个字只有4个字节,
lsl#2
。(是一个C编译器使用它来验证语法的示例)。但无论如何,这应该比用
lsl
add
指令手动进行地址计算更容易。在循环中调用
printf
很奇怪,通常您只需要使用调试器,但我认为这很好。您的代码似乎不依赖于r0..r3或r12中的任何一个在整个调用中幸存,并且根据所有r4..r11都是保留调用的。谢谢!我解决了这个问题。我需要使用ldrb和strb来正确读取整数。但是我必须读入32位整数,所以我想知道我要怎么做才能读入32位整数。我是否只需要更改说明符以及加载和存储指令?因此,如果我希望我的代码能够读取32位整数,我是否需要要求所有整数都是32位长的?当然,如果您读取的是32b值,则该值必须是内存中的32b值。在保存/加载之前,您可以上下缩放值,并使其具有不同的格式,但您应该始终以与写入值相同的格式读取。
0x00000000: 01 
0x00000001: 02 
0x00000002: 03 
0x00000003: 04 

or same in one line
0x00000000: 01 02 03 04