2017-02-16 42 views
0

(この問題は、アセンブリ言語のARMに基づいています。) 私は特定の配列を逆にするように私に尋ねる問題に対処しています。ただ、このような :アセンブリ言語で配列を逆にする方法は?

 Given array: 1, 2, 3, 4, 5 
     Reversed array: 5, 4, 3, 2, 1 

そして、この問題の制限は、私が唯一のレジスタR0-R3を使用するようになってるということです。

私は基本的なアルゴリズムを持っていますが、アイデアを実装しようとすると本当に混乱します。 私のアルゴリズム:

Loop: 
     1. get value from head pointer, ptr++ 
     2. get value from tail pointer, ptr-- 
     3. swap them 
     4. check if head pointer and tail pointer cross, 
     if so, exit loop and return. 
     if not, go back to loop. 

しかし、私はちょうどこの問題を解決するためにのみ4つのレジスタを使用する方法がわからない...

以下

は、私が現在持っているすべてのだろう。

.text 
.global reverse 

reverse: 
    @ See if head and tail ptr cross 
    @ If so, end loop (b end) 

head: 
    @ use r2 to represent head value 
    ldr r2,[r0]  @ r2 <-*data get the first value 

tail: 
    @ mov r1,r1  @ size 
    sub r1,r1,#1 @ size-1 
    lsl r1,r1,#2 @ (size-1)*4 
    add r0,r0,r1 @ &data[size-1]  need to ldr r1,[r0] to get value 
    ldr r1,[r0]  @ get value for r1 (from tail) 

swap: 
    @ swap values 
    mov r3, r1  @store value to r3 
    str r2, [r0] 
    @ head ptr ++ 
    @ tail ptr -- 
    @ back to reverse 

end: 
    @ loop ends 
+0

あなたのアルゴリズムは不完全である、それは永遠に頭と尾の値を交換します。 – Ped7g

+0

Cでこれをコンパイルして、それを分解して研究してみてはどうでしょう。なぜなら、フードの下にあるものを知りたがっているときです。 –

+1

あなたのアルゴリズムが永久に頭+1と尾-1 (もしそれらが存在していても、 'ptr'という単語が特定の頭/尾のポインタを意味し、全く異なるものではない場合)...適切に書き留めてください。実際には簡単で簡単なステップに書き留めることを躊躇しないでください。それは、asmの書き込みに本当に役立つかもしれません。 – Ped7g

答えて

1

原油と非効率的な例

.data 
     Array: .word 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,32,64,128,256,512 
     .equ len.Array,.-Array 
.text 
     .global main 
main: 
     nop 

     sub sp, sp, #len.Array   // save space on stack 

     ldr r1,=Array     // Array 
     mov r2, #len.Array    // length of array 
     mov r3, #0      // zero init counter Array 
     1: 
       ldr r0, [r1,r3]   // load word size element position x from Array 
       push {r0}    // push element value into stack 
     add r3, r3, #4     // inc Array counter by 4 since word size is 4 bytes 
     cmp r3, r2      // 
     blt 1b 

     // pop values off the stack - LIFO results in reversal 

     mov r3, #0      // zero init counter Array 
     2: 
       pop {r0}  // pop element value from stack - LIFO 
       str r0, [r1,r3] 

     add r3, r3, #4     // inc Array counter by 4 since word size is 4 bytes                           cmp r3, r2 
     blt 2b                                                                                             add sp, sp, #len.Array   // restore stack pointer 

GDB出力:

(gdb) x/21d $r1 
0x1102d:  1  2  3  4 
0x1103d:  5  6  7  8 
0x1104d:  9  10  11  12 
0x1105d:  13  14  15  16 
0x1106d:  32  64  128  256 
0x1107d:  512 


(gdb) x/21d $r1 
0x1102d:  512  256  128  64 
0x1103d:  32  16  15  14 
0x1104d:  13  12  11  10 
0x1105d:  9  8  7  6 
0x1106d:  5  4  3  2 
0x1107d:  1 
関連する問題