2016-04-19 12 views
0

Für eine Hausaufgabe wurde mir eine rekursive C-Funktion gegeben, um ganzzahlige Partitionen zu zählen, die ich in eine ARM-Assembly konvertieren muss. Dinge, die ich weiß, über ARM assembly:Konvertierung der rekursiven C-Funktion in ARM-Assembly?

1) R0 wird der Rückgabewert eines Anrufs

2) R1, R2, halten und R3 sind Argument

Der Code registriert ist wie folgt:

int count_partitions(int n, int m) { 

if (n == 0) 
    return 1; 

else if(n < 0) 
    return 0; 

else if (m == 0) 
    return 0; 

else 
    return count_partitions(n - m, m) + count_partitions(n, m - 1); 
} 

Ich glaube, ich habe die ersten 3 if & else-if Anweisungen richtig gemacht. Meine Logik für die letzte else Anweisung war, count_partitions (n, m-1) zu finden, diese auf dem Stack zu speichern, dann count_partitions(n-m, m) zu finden und das zum vorherigen Rückgabewert hinzuzufügen, den ich vom Stack bekommen habe - aber mein Code scheint das nicht zu sein Arbeit?

Ich habe meine Lösungsansätze angefügt und habe die verschiedenen Segmente von C-Code und ihren entsprechenden Assemblercode farblich codiert. Könnte mich jemand wissen lassen, was los ist?

enter image description here

+1

Haben Sie versucht, die gcc (oder clangs) Fähigkeit Assembler-Code für die Führung zu generieren? –

+0

Ich kann das winzige unlesbare Bild des Codes nicht ganz entziffern, aber [hier ist, was ein Compiler denkt] (https://gcc.godbolt.org/#compilers :! ((compiler: armhfg482, Optionen: '- O2 + -marm ', source:' int + count_partitionen (int + n, + int + m) +% 7B +% 0Aif + (n +% 3D% 3D + 0) +% 0A ++++ return + 1% 3B +% 0Aelse + if (n + % 3C + 0) +% 0A ++++ Rendite + 0% 3B +% 0Aelse + wenn + (m +% 3D% 3D + 0) +% 0A ++++ Rendite + 0% 3B +% 0Areturn + Anzahl_Partitionen (n + - + m, + m) +% 2B + Zählpartitionen (n, + m + - + 1)% 3B +% 0A% 7D ')), filterAsm: (Anweisungen:! t, Labels:! t), Version: 3), wie auch immer. – Notlikethat

+0

Es scheint sehr unwahrscheinlich, dass Sie jemals Assembler und Rekursion in einer realen Anwendung kombinieren müssen.Reale Anwendungen für Rekursion sind sehr selten, in fast allen Fällen gibt es eine bessere, nicht-rekursive Alternative. Insbesondere die Rekursion in eingebetteten Systemen ist in 99,99% der Fälle reiner Unsinn. Es ist eine gute Möglichkeit, eine Klage zu bekommen. – Lundin

Antwort

0

Sie können dies nach dem Befehl CMP verwenden und springen Ihre Funktion:

BEQ Etikett; BRAND EQUAL

BNE-Etikett; ZWEIG NICHT GLEICH

BLE-Etikett; BRANCHE WENIGER ALS EQUAL

BLT-Label; BRANCHEN WENIGER ALS

BGE-Etikett; Verzweigung größer als gleich

BGT-Label; BRANCHEN GRÖSSER ALS

0

Ich glaube, ich mehrere Probleme sehen:

  • Sie gehen davon aus, dass n in r1 ist. Dies ist tatsächlich in r0. m wird in r1, nicht r2 sein.
  • Aus diesem Grund müssen Sie sowohl r0 als auch r1 speichern.

Eine sauberere Lösung wäre, so etwas zu verwenden:

_count_partitions: 
    ...    ; First part with comparison 
        ; but r1->r0 and r2->r1 

    push {r4-r5} 
    mov r4, r0  ; saved value of n 
    mov r5, r1  ; saved value of m 
    sub r0, r4, r5 ; n = n-m 
    bl _count_partitions 

    sub r1, r5, #1 ; m = m-1 
    mov r5, r1  ; result of first function 
    mov r0, r4  ; restore n 
    bl _count_partitions 

    add r0, r0, r5 ; cumulative result 
    pop {r4,r5} 
    pop {pc} 
Verwandte Themen