Forum: Compiler & IDEs Assembler Frage ( 2mal hintereinander dieselbe Instruktion )


von Espen A. (espen)


Lesenswert?

Werte Leser,
ich bin mir nicht ganz sicher, ob hier das richtige Forum ist, aber es 
scheint mir das am wenigsten falsche zu sein ;)
Ich habe eine Assemblerstrecke da taucht zweimal direkt hintereinander
dieselbe Instruktion auf. So sieht das aus:

cmp r0,#0
cmp r0,#0

Ich habe auch geguckt, ob da ein Sprunglabel ist. Ist aber nicht.
Was soll so etwas?
Gruß
Espen

von (prx) A. K. (prx)


Lesenswert?

Assembler-Quellcode? Bei disassembliertem Code können es mitten drin 
eingebettete Daten sein, oder Füllbytes für Alignment.

von Gerald K. (geku)


Lesenswert?

Espen A. schrieb:
> Was soll so etwas?

Ergibt eine Zeitverzögerung, oder es war ein Copy/Past Fehler.

von Espen A. (espen)


Lesenswert?

"Bei disassembliertem Code"
Das könnte es tatsächlich sein, da muss ich mal forschen. Danke!

von ARM007 (Gast)


Lesenswert?

> ... Assemblerstrecke ...

Wo kommt die her? Welcher Prozessor?

von Espen A. (espen)


Lesenswert?

Das ist ein arm compiler für einen STM32F4.
Und jetzt habe ich mir auch den Hexcode angeguckt und der sieht so aus:

2800 cmp r0,#0
2800 cmp r0,#0

und der wird auch ausgeführt, ich hab da reingebreakt.

Beitrag #6723767 wurde vom Autor gelöscht.
von Espen A. (espen)


Lesenswert?

>würde ich sagen MCS-51
nönönö ist ein 32bitter.

von (prx) A. K. (prx)


Lesenswert?

Espen A. schrieb:
> und der wird auch ausgeführt, ich hab da reingebreakt.

Schreib die Adressen dazu. Sprungziel dahinter?

: Bearbeitet durch User
von Espen A. (espen)


Lesenswert?

08005858:   cmp     r0, #0
0800585a:   cmp     r0, #0

von (prx) A. K. (prx)


Lesenswert?

Alignment fällt aus.

von Espen A. (espen)


Lesenswert?

"Bearbeiten" scheint nicht zu funktionieren. Dann kommt
0800585c:   bne.n   0x800584c

Gibt es nicht vielleicht so einen allgemeinen Grund "wie flush buffer" 
oder so?

von (prx) A. K. (prx)


Lesenswert?

Rück halt etwas mehr Kontext raus, deine Salamischeiben sind zu dünn.

: Bearbeitet durch User
von Espen A. (espen)


Lesenswert?

>"Rück halt etwas mehr Kontext raus, deine Salamischeiben sind zu dünn."
Ich hab nur die Codestrecke von __sync_val_compare_and_swap( &lock,0,1 )
1
 8005844:  463a        mov  r2, r7
2
 8005846:  2101        movs  r1, #1
3
 8005848:  f3bf 8f5b   dmb  ish
4
 800584c:  e852 3f00   ldrex  r3, [r2]
5
 8005850:  2b00        cmp  r3, #0
6
 8005852:  d104        bne.n  800585e <main+0x66>
7
 8005854:  e842 1000   strex  r0, r1, [r2]
8
 8005858:  2800        cmp  r0, #0
9
 800585a:  2800        cmp  r0, #0
10
 800585c:  d1f6        bne.n  800584c <main+0x54>
11
 800585e:  f3bf 8f5b   dmb  ish
12
 8005862:  60bb        str  r3, [r7, #8]

Mod: Formatierung angepasst.

: Bearbeitet durch Moderator
von (prx) A. K. (prx)


Lesenswert?

Espen A. schrieb:
> Gibt es nicht vielleicht so einen allgemeinen Grund "wie flush buffer"
> oder so?

Das sind die DMB Befehle davor und dahinter.

von Spätz-Jalist (Gast)


Lesenswert?

>> Assembler Frage ( 2mal hintereinander dieselbe Instruktion )

Das ist für den Fall, das der Prozessor den Befehl beim ersten Mal nicht 
verstanden hat. Er legt dann die Frage "Hä?!" auf den Datenbus.

von Gerald K. (geku)


Lesenswert?

Könnte es,  dass der Grund mit dem Carry-Flag zu tun hat?

https://stackoverflow.com/questions/44620368/cmp-and-carry-flag

CMP verwendet das Carry-Flag und setzt dieses wiederum. Daher müssen die 
Flags beim ersten und zweiten CMP Aufruf nicht gleich sein, oder irre 
ich mich?

von (prx) A. K. (prx)


Lesenswert?

CMP setzt das C Flag, nutzt es aber nicht als Input. Das tut SBC, 
Subtraktion mit Carry.

Die Semaphor-Operation hier findet sich in Varianten auch in etlichen 
Beispielen, dort aber mit einem CMP.

Zu einem Fehler des Cortex Core bei STREX fand ich auch nichts.

: Bearbeitet durch User
von Gerald K. (geku)


Lesenswert?

(prx) A. K. schrieb:
> nutzt es aber nicht als Input

Wird es für den Größer/Kleinervergleich nicht benutzt?

von Espen A. (espen)


Lesenswert?

Erstmal besten Dank für die bisherige Unterstützung, wenn ich auch nicht 
immer alles verstehe.
Die obige Codestrecke ist das Kompilat ohne Optimierung.
Wenn ich mit -Os kompiliere, fehlt der doppelte Vergleich und diese 
Codestrecke wird generiert:
1
80039d8:  bf00        nop
2
    val = __sync_val_compare_and_swap( &lock,0,1 );
3
 80039da:  2601        movs  r6, #1
4
 80039dc:  f3bf 8f5b   dmb  ish
5
 80039e0:  e854 2f00   ldrex  r2, [r4]
6
 80039e4:  42aa        cmp  r2, r5
7
 80039e6:  d103        bne.n  80039f0 <main+0x5c>
8
 80039e8:  e844 6300   strex  r3, r6, [r4]
9
 80039ec:  2b00        cmp  r3, #0
10
 80039ee:  d1f7        bne.n  80039e0 <main+0x4c>
11
 80039f0:  f3bf 8f5b   dmb  ish
12
    __ASM( "nop" );
13
 80039f4:  bf00        nop

Das sieht für mich proper aus.
Dies nur zur Info und die nops sind natürlich von mir.

Mod: Formatierung angepasst.

: Bearbeitet durch Moderator
von (prx) A. K. (prx)


Lesenswert?

Gerald K. schrieb:
> (prx) A. K. schrieb:
>> nutzt es aber nicht als Input
>
> Wird es für den Größer/Kleinervergleich nicht benutzt?

Nicht als Input zu CMP, nur als Output.

von (prx) A. K. (prx)


Lesenswert?

Espen A. schrieb:
> __sync_val_compare_and_swap

Davon könnte der Sourcecode interessant sein.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Espen A. schrieb:
> Wenn ich mit -Os kompiliere, fehlt der doppelte Vergleich und diese
> Codestrecke wird generiert:

Bitte zukünftig die Code-Teile in [ code ] ... [ /code ] (ohne 
Leerzeichen) einpassen, sonst steht das auf Mobilteilen alles in einer 
Zeile und wird dadurch unleserlich.

Ich habe die oben stehenden Beiträge mal angepasst. Bitte zukünftig 
selber machen. Danke.

von Espen A. (espen)


Lesenswert?

(prx) A. K. schrieb:
> Davon könnte der Sourcecode interessant sein.

Ich hab ihn nicht, versuch ihn zu kriegen, kann aber dauern.

von Hp M. (nachtmix)


Lesenswert?

Espen A. schrieb:
> Die obige Codestrecke ist das Kompilat ohne Optimierung.
> Wenn ich mit -Os kompiliere, fehlt der doppelte Vergleich

Da hatte der Compiler ursprünglich wohl zwei Codefragmente 
aneinandergekleistert, von denen das erste mit dem CMP aufhört, als 
Vorbereitung darauf was meist folgt, z.B. RET mit gesetzten Flags,
und  einem zweiten Fragment, das mit  der Abfrage auf 0 beginnt, weil 
sofort danach die Verzweigung erfolgt.

Schadet ja nichts.

Der Optimizer hat das dann bemerkt und den ersten CMP entfernt.

P.S.:
Dass die optimierte Version andere Register verwendet, dürfte daran 
liegen, dass der Optimizer vorher schon manche überflüssigen Umladungen 
entfernt hat.

: Bearbeitet durch User
von Programmierer (Gast)


Lesenswert?

Unoptimierter Assembler-Code enthält jede Menge redundanten Blödsinn. Es 
ist ziemlich nutzlos, sich solchen Code anzusehen.

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.