2017-11-13 3 views
0

Ich analysiere die folgende ARM-Assembly im VIsUAL-Emulator, einer einfachen Funktion, die ein Array von Konstanten durchläuft und die größte Zahl auswählt.Warum ist eine Verschiebung erforderlich, um auf die Array-Position zuzugreifen?

mov  r0, r13   ; pass the memory address where you stored the array's contents 
    mov  r1, #20  ; pass the second argument count to the function 

    mov  r5, #04    
    mov  r6, #01    
    mov  r7, #13    
    mov  r8, #42    
    mov  r9, #25    
    stmfa r13, {r5,r6,r7,r8,r9} 
    bl  max 
    end 
max 
    mov  r2, #0 
L2 
    cmp  r2, r1 
    bge  L5 
    ldr  r12, [r0, r2, lsl #2] 
    add  r2, r2, #1 
    cmp  r3, r12 
    movlt r3, r12 
    b  L2 
L5 
    mov  r0, r3 

Es funktioniert bestimmt als nur eine Sache, die ich nicht verstehe, ist in:

ldr  r12, [r0, r2, lsl #2] 

Es ist in r12 Laden den der aktuelle Wert des Feldes, dessen Start durch r0 in der spitz aktueller Index r2, aber warum gibt es dort eine logische Verschiebung?

+2

Da Wörter 4 Bytes sind, müssen Sie um 4 skalieren, was eine Verschiebung von links nach links ist. – Jester

Antwort

2

Dies wird getan, um die Größe der Elemente im Array zu berücksichtigen. In diesem Fall sieht es so aus, als ob der Code auf Elemente mit 4 Byte Größe zugreift, möglicherweise ein int in C (zum Beispiel auf einem ILP32-System).

Der Schleifenzähler in r2 wird bei jeder Iteration der Schleife um 1 inkrementiert, aber jedes Element im Array ist 4 Byte vom vorherigen Element entfernt. Nehmen Sie also an, dass der Anfang des Arrays in r0 liegt Ihr Zugriffsmuster ist [r0 + 0], [r0 + 4], [r0 + 8]... anstatt [r0 + 0], [r0 + 1], [r0 + 2]..., weshalb ein Skalierungsfaktor von 4 erforderlich ist.

+1

Ja, alle Standard-ABIs für 32-Bit-ARM sind ILP32, also könnte dies auch ein Array von sein 'lang' (aber wahrscheinlich keine Zeiger basierend auf der Operation, die an ihnen ausgeführt wird). –

Verwandte Themen