【问题标题】:Returning from ARM7 nested subroutine从 ARM7 嵌套子程序返回
【发布时间】:2012-11-15 21:18:55
【问题描述】:

好的,我正在尝试在 ARM7 Assembly 中实现选择排序算法。它从数组的最后一个元素开始,一直到第一个元素。它适用于第一次交换,但在继续之前退出。我和我的教授谈过,他说要使用堆栈变量,这样 lr 就不会被覆盖等,但我仍然不明白该怎么做。我已经搜索了执行此操作的方法,但似乎找不到任何我理解如何在我的代码中实现的内容。

我的代码如下:(a1是指向长度为a2的char数组的指针。两者都是通过C传入的)

sort2:
    stmdb    sp!, {v1-v8, lr}          @ Copy registers to stack
    mov      v1, a2                    @store number of elements in v1,v2 (a2 is passed in via C)
    mov      v2, a2
    sub      v1, v1,#1                 @subtract 1 from a2 to get number last element in array
    sub      v2, v1,#1                 @subtract 1 from v1 to get element just below last element
    bl       loop2
    ldmia    sp!, {v1-v8, pc}

loop2:
    ldrb     v4, [a1,v1]               @store value of last element in array a1(passed in via C) into r4 
    ldrb     v5, [a1,v2]               @store value of next to last element in array a1(passed in via C) into r4 
    cmp      v4, v5
    blt      swap2                     @if last element is less than current element a[v2], swap them
    cmp      v2, #0                    @if v2 = 0, we cycled through one iteration
    subeq    v1, v1,#1                 @so now move on to a[v1-1] element in array                   
    moveq    v2, v1                    @if v2 = 0, move the value of v1 into v2
    sub      v2, v2,#1                 @subtract 1 from v2 to get element below a[v1]
    cmp      v1, #0                    @if v1 = 0, were done
    bne      loop2
    mov      pc, lr                    @return to sort2

swap2:
    mov      v8, lr                    @store return address in v8
    ldrb     v6, [a1,v2]               @store value of a[v2] into v6
    strb     v4, [a1,v2]               @store v4 into a[v2]
    strb     v6, [a1,v1]               @store value of v6 into a[v1]
    mov      lr, v8                    @falls through and exits here instead of returning to loop2

【问题讨论】:

    标签: assembly arm instruction-set arm7


    【解决方案1】:

    已经有几个地方可以从子程序返回。

    当你输入sort2时,你会在堆栈中保存一些寄存器:

    stmdb    sp!, {v1-v8, lr}          @ Copy registers to stack
    

    当你离开sort2时,你会从堆栈中恢复一些寄存器:

    ldmia    sp!, {v1-v8, pc}
    

    当你离开loop2时,你会做类似的事情:

    mov      pc, lr                    @return to sort2
    

    仔细看看。注意到那里的模式了吗?离开swap2应该有类似的东西。

    现在,loop2 应该调用另一个函数:swap2。为了支持调用其他函数,调用函数应该保存一些寄存器,就像sort2一样。叶函数(不调用其他函数的函数)不需要保存调用者保存的寄存器。此外,正如@PeteFordham 已删除的答案所指出的那样:blt = branch on less than; bllt = 分支和链接小于

    【讨论】:

    • 所以我需要在blt 调用之前将stmdb sp!, {v1-v8, lr} 添加到loop2(并切换blt to bllt)?然后在swap2 末尾有一个mov pc, lr
    猜你喜欢
    • 1970-01-01
    • 2016-04-08
    • 1970-01-01
    • 2019-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-10
    • 1970-01-01
    相关资源
    最近更新 更多