19.06.2014 Aufrufe

Debugging mit bedingten Befehlen auf ARM-CPUs - EuE24.net

Debugging mit bedingten Befehlen auf ARM-CPUs - EuE24.net

Debugging mit bedingten Befehlen auf ARM-CPUs - EuE24.net

MEHR ANZEIGEN
WENIGER ANZEIGEN

Erfolgreiche ePaper selbst erstellen

Machen Sie aus Ihren PDF Publikationen ein blätterbares Flipbook mit unserer einzigartigen Google optimierten e-Paper Software.

E&E PRODUCTS & SOLUTIONS<br />

MIKROCONTROLLER & PROZESSOREN<br />

B.01<br />

gefügt. Das Feld cond bestimmt hierbei, abhängig<br />

von den Flags N, Z, C und V im Statusregister<br />

CPSR, ob der Befehl ausgeführt<br />

wird oder nicht. Für die Bedingungen ergeben<br />

sich da<strong>mit</strong> insgesamt 16 Fälle:<br />

Die Mnemonic-Erweiterung wird hierbei an<br />

den Assembler-Befehl angehängt, wobei für<br />

Befehle ohne Bedingung die Erweiterung al<br />

in der Regel entfällt. Für den Befehl<br />

add r2, r2, #1 ; inkrementiere Register r2<br />

ergibt sich im Falle der Bedingung „Ausführen<br />

bei Gleichheit“ Z=1 der Befehl<br />

addeq r2, r2, #1 ;<br />

inkrementiere Register r2 wenn Z=1.<br />

Im Falle von Z=0 wird r2 nicht inkrementiert.<br />

Im folgenden Abschnitt werden Beispiele<br />

angeführt.<br />

C-Code versus Assembler-Code<br />

Beispiel 1<br />

# “C” Code <strong>ARM</strong> Assembler<br />

Code<br />

1 if (index < counter) ldrh r2, [r5]<br />

2 { ldrh r3, [r4, #00h]<br />

cmp r2, r3<br />

3 buffer1 = index; movcc r7, r2<br />

4 }<br />

5 else<br />

6 {<br />

7 buffer2 = index+1; ldrcs r3, [pc, #1ch]<br />

ldrcsb r6, [r3]<br />

addcs r6, r6, #1h<br />

9 }<br />

Abb. 1:<br />

Den „<strong>bedingten</strong>“<br />

Breakpoint, erkennt<br />

man am Fragezeichen<br />

im Punkt, den un<strong>bedingten</strong><br />

Breakpoint<br />

am Punkt<br />

Hier werden drei Beispiele für bedingte Anweisungen<br />

in C- und Assembler-Code gezeigt.<br />

Der C-Code wurde dabei <strong>mit</strong> einem<br />

<strong>ARM</strong>-GNU-Compiler übersetzt. Die den C-<br />

Anweisungen entsprechenden Assembler-<br />

Instruktionen sind zur Verdeutlichung in<br />

Gruppen zusammengefasst. Ein einfaches<br />

Beispiel für eine „if-then-else“-Bedingung in<br />

C und Assembler zeigt Beispiel 1.<br />

Diese in C absolut übliche Konstruktion<br />

einer Abfrage erzeugt im Assembler-Code<br />

eine lineare Abfolge von <strong>Befehlen</strong> ohne<br />

Sprünge. Abhängig vom Carry-Flag werden<br />

die Befehle ausgeführt oder nicht (ersichtlich<br />

an den Mnemonic-Erweiterungen cc<br />

und cs, siehe vorherige Tabelle). Der Vorteil<br />

ist eine konstante L<strong>auf</strong>zeit des Codes, unabhängig<br />

von der Gültigkeit der Abfrage-<br />

Bedingung in Zeile #1. Es werden immer<br />

sowohl der „if“-Zweig als auch der „else“-<br />

Zweig durchl<strong>auf</strong>en.<br />

Für Prozessoren ohne bedingte Befehle werden<br />

Assembler-Anweisungen generiert, die<br />

die „if-then-else“-Pfade über Sprungbefehle<br />

erreichen. Dazu wird nach der Abfrage der<br />

Bedingung in Zeile #1 ein bedingter Sprung<br />

eingefügt, und im „if“-Zweig der „else“-<br />

Zweig übersprungen und umgekehrt. Dies<br />

ist in Beispiel 2 zu sehen. Hier wird der Programmabl<strong>auf</strong><br />

durch Sprünge gesteuert,<br />

wo<strong>mit</strong> die L<strong>auf</strong>zeit vom durchl<strong>auf</strong>enen Pfad<br />

abhängt. Dies ist an der Anzahl der ausgeführten<br />

Befehle leicht zu erkennen (Vergleich<br />

der Zeilen #3 und #7).<br />

Beispiel 3 zeigt, wie durch eine zusätzliche<br />

Abfragebedingung im Beispiel 1 ein <strong>ARM</strong><br />

Assembler-Code wie bei Beispiel 2 erzeugt<br />

wird. Hier wird der Programmabl<strong>auf</strong> ebenfalls<br />

durch Sprünge gesteuert.<br />

Die Zeilen #7 aller Beispiele erzeugen dieselbe<br />

Folge von Assemblerbefehlen, <strong>mit</strong> dem<br />

Unterschied, dass sie in Beispiel 1 bedingt<br />

ausgeführt werden, während sie in Beispiel 2<br />

und 3 immer (Bedingung „Always“, siehe<br />

vorherige Tabelle) ausgeführt werden. Die<br />

Mnemonic-Erweiterung wird hierbei, wie<br />

bereits erwähnt, nicht angezeigt.<br />

Für den Software-Entwickler ist da<strong>mit</strong> nicht<br />

unbedingt zu erkennen, welcher Programmcode<br />

erzeugt wird und wie das L<strong>auf</strong>zeitverhalten<br />

sein wird. Der generierte <strong>ARM</strong>-Assembler-Code<br />

hängt im Wesentlichen davon<br />

ab, wie komplex die Anweisungen in der<br />

„if“-Bedingung und innerhalb der beiden<br />

Pfade sind und welche Register zur Verfügung<br />

stehen.<br />

Debug-Problematik<br />

Das Debuggen solcher Programmabläufe<br />

<strong>mit</strong> Breakpoints führt zu unterschiedlichen<br />

Resultaten:<br />

Bei einem Breakpoint in Zeile #7 des C-Codes<br />

wird eine Programmunterbrechung erwartet,<br />

falls die Bedingung in Zeile #1 nicht erfüllt ist.<br />

Für die Beispiele 2 und 3 trifft dies zu. In Beispiel<br />

1 jedoch wird die Programmausführung<br />

in jedem Fall in Zeile #7 angehalten, da immer<br />

beide Zweige durchl<strong>auf</strong>en werden. Was<br />

Beispiel 2<br />

# “C” Code <strong>ARM</strong> Assembler<br />

Code<br />

1 if (index < counter) ldrh r2, [r5]<br />

2 { ldrh r3, [r4, #00h]<br />

cmp r2, r3<br />

bcs #else<br />

3 buffer1 = index; mov r7, r2<br />

ble #end<br />

4 }<br />

5 else #else<br />

6 {<br />

7 buffer2 = index+1; ldr r3, [pc, #1ch]<br />

ldrb r6, [r3]<br />

add r6, r6, #1h<br />

9 } #end<br />

Beispiel 3<br />

# “C” Code <strong>ARM</strong> Assembler<br />

Code<br />

1 if ((index < counter) && ldrh r2, [r5]<br />

(buffer1+buffer2 < 25)) ldrh r3, [r4, #00h]<br />

2 { cmp r2, r3<br />

bcs #else<br />

add r3, r7, r6<br />

cmp r3, #18h<br />

movle r7, r2<br />

ble #end<br />

3 buffer1 = index;<br />

4 }<br />

5 else #else<br />

6 {<br />

7 buffer2 = index+1; ldr r3, [pc, #1ch]<br />

ldrb r6, [r3]<br />

add r6, r6, #1h<br />

9 } #end<br />

92<br />

www.<strong>EuE24.net</strong>

Hurra! Ihre Datei wurde hochgeladen und ist bereit für die Veröffentlichung.

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!