Forum: Mikrocontroller und Digitale Elektronik ARM Assembly: Warum nop?


von Walter T. (nicolas)


Angehängte Dateien:

Lesenswert?

Hallo,

ich habe mir gerade ein ASM-Listing für einen Cortex M4F angeschaut, 
weil mich interessiert hat, ob eine "normale" C-Funktion in diesem Fall 
irgendeinen Nachteil gegenüber einer static inline-Funktion hat.

Das Assembler-Listing ist im Anhang.

Dabei aufgefallen sind mir zwei NOP-Instruktionen, deren Zweck ich nicht 
verstehe, nämlich die Zeilen 62 und 68.

Mein erster naiver Gedanke war, dass das NOP in Zeile 62 dafür da 
gewesen wäre, das erste WORD an einer durch 4 teilbaren Adresse 
auszurichten - aber dann wäre das zweite NOP in Zeit 68 nicht da, 
sondern das WORD danach zwei Zeilen früher. Und warum ein NOP? Warum 
nicht ein SHORT 0?

Jetzt bin ich verwirrt. Wer kann mich aufklären?

: Bearbeitet durch User
von Eine Vermutung (Gast)


Lesenswert?

Anscheinend arbeitet der Optimizer noch nicht perfekt.

Der könnte zwar beide nop vermeiden, wenn er den Speicherplatz für die 
Konstanten vertauscht. Hat aber noch niemand implementiert.

von Rüdiger B. (rbruns)


Lesenswert?

Das habe ich auch in Assemblern gehabt, es wird ein 16 Bit Sprung 
vorgesehen da das Sprungziel nicht bekannt ist, aber später mit einem 8 
Bit Sprung ausgeführt wird. Da wird nicht genügend Optimiert.

von (prx) A. K. (prx)


Lesenswert?

Der Grund ist Alignment auf eine 4-Byte Grenze.

von Rüdiger B. (rbruns)


Lesenswert?

(prx) A. K. schrieb:
> Der Grund ist Alignment auf eine 4-Byte Grenze.

Stimmt!!!!

von (prx) A. K. (prx)


Lesenswert?

NOP wird verwendet, weil der dies einfügende Assembler oder Linker sich 
dann nicht darum kümmern muss, ob es ein Daten- oder Codebereich ist.

von Walter T. (nicolas)


Lesenswert?

Danke, das klingt plausibel.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

1
 80074f4:  30767264   .word  0x30767264
2
 80074f8:  696e695f   .word  0x696e695f
3
 80074fc:  0074        .short  0x0074
4
 80074fe:  bf00        nop
5
 8007500:  ff00000c   .word  0xff00000c

Das sind Daten, keine Befehle. Das erste dürfte der String "drv0_init\0" 
sein. Wofür die weiteren 0x00 0xbf 0x0c 0x00 0x00 0xff sind, erschließt 
sich mir so direkt nicht.

von Andras H. (kyrk)


Lesenswert?

Jörg W. schrieb:
> 0x00 0xbf 0x0c 0x00 0x00 0xff

Nur 0xbf 0x0c 0x00 0x00 0xff
Weil der 0x00 am anfang noch zu dem String gehört. Null terminated 
string brauch am ende den 0, sonst weiss man nicht wo es endet.

Der NOP kann dann wegen aligment da sein.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Andras H. schrieb:
> Nur 0xbf 0x0c 0x00 0x00 0xff
> Weil der 0x00 am anfang noch zu dem String gehört.

Nö, die 0 dafür steht bereits auf 0x80074fd. Die auf 0x80074fe ist was 
anderes.

Beachte, dass die Zahlendarstellung der Strings little-endian ist, was 
die Zeichenfolge "unlogisch" herum dreht. (Das war ja letztlich der 
Vorteil von big-endian, es ist egal, ob man auf die Zahlengruppen in 8, 
16 oder 32 Bit draufschaut, sie sehen immer gleich angeordnet aus.)

von Walter T. (nicolas)


Lesenswert?

Jörg W. schrieb:
> Das erste dürfte der String "drv0_init\0"
> sein.

Alle Achtung, dass Du das im Kopf siehst. Ich habe mir gerade erstmal 
ein Skript geschrieben, um das zu prüfen.

So sehen also Debug-Symbole aus. Wieder etwas gelernt. Was mich gerade 
richtig ärgert ist, dass ich mir die Frage danach vorher noch nie 
gestellt habe.

: Bearbeitet durch User
von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Walter T. schrieb:
>> Das erste dürfte der String "drv0_init\0"
>> sein.
>
> Alle Achtung, dass Du das im Kopf siehst.

Die Vermutung, dass da ASCII-Zeichen stehen, war mir tatsächlich beim 
Anblick solcher Zahlen gekommen. Für den String selbst habe ich dann 
aber schon eine ASCII-Tabelle genommen. ;-)

Reine Debugsymbole wandern eigentlich nicht ins Binary hinein, also 
nicht in den in den Flash geladenen Teil. Da musst du irgendwas in 
deinem Code drin haben, was den Funktionsnamen als String reinzieht (den 
bekommt man in C ja über einen vom Standard definierten Makro 
geliefert).

von Walter T. (nicolas)


Lesenswert?

Wie habe ich eine Chance herauszubekommen, was das ist?

Die Funktionen selbst können es nicht sein - in der zitierten Funktion 
ist nichts derartiges. Dort wird nur eine globale Variable in eine 
andere globale Variable kopiert. Keine Fehlerbedingung, keine Assertion.

Praktisch ist das nicht so wichtig. Ich habe noch viel, viel Flash 
übrig. Aber neugierig bin ich schon.

: Bearbeitet durch User
von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Schwierig von der Ferne zu sagen. Irgendwer muss den String ja 
referenzieren, aber ob man das im Disassembly so direkt erkennt?

Hast du sowas wie assert() benutzt?

von Jim M. (turboj)


Lesenswert?

Das sind keine Debug Symbole - die landen wie schon erwähnt nicht im 
flash - sondern eher Debugging Code analog zu
1
void drv0_init()
2
{
3
  printf("drv0_init");
4
}

Die Strings müssen im Flash relativ dicht bei der verwendenden Funktion 
liegen wenn man deren Adresse mit einem einzigen 16-Bit Befehl laden 
möchte.

von Walter T. (nicolas)


Lesenswert?

Ich finde zumindest nichts im Disassembly, was 0x80075aXX lädt.

assert()/error() nutze ich - nicht in dieser Funktion, aber in dieser 
.c-Datei.

Gäbe es "verdächtige" Compiler-Optionen? Das Flag "-G3" war es auf jeden 
Fall nicht.

Einen Modultest zu dieser Funktion gibt es auch nicht.

Aber die Funktionsnamen jeder Funktion liegen tatsächlich als 
Zeichenkette im Flash.

: Bearbeitet durch User
von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Kannst du den Sourcecode der Funktion (und ggf. die Compileroptionen) 
denn hier posten?

von Walter T. (nicolas)


Lesenswert?

"Sicher, an meinen Spielereien ist nichts geheim." - wollte ich gerade 
posten.

Aber in der Vorbereitung, das Build-Log ein wenig von langweiligen 
Dateilisten zu säubern, damit es überhaupt zumutbar ist, dort 
hineinzuschauen, habe ich den "Übeltäter" gefunden: 
"-mpoke-function-name"

Ich habe nur nicht mehr die geringste Ahnung, warum ich das wohl 
aktiviert habe und was ich mir davon versprochen habe.

Da heisst es wohl, handschriftliche Notizen zu durchsuchen. :-(

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Interessant, kannte ich noch gar nicht.

Schön, dass du's auf diese Weise gefunden hast.

von foobar (Gast)


Lesenswert?

Ansonsten auch mal mit -S oder --save-temps compilieren und sich das 
generierte <foo>.s anschauen.  Dann sieht man, was der Compiler 
generiert hat und nicht das, was Assembler und Linker daraus gemacht 
haben bzw der Disassembler sich zusammengereimt hat.  Bei den NOPs z.B. 
könnte da ein ".align irgendwas" stehen.

Beitrag #7229723 wurde von einem Moderator gelöscht.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.