PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Symbol "loop_label" is already defined



7.e.Q
26-09-2006, 10:47
Hi Leute,

ich hab hier ein kleines Problem:
Ich hab in einem Programm eine Funktion die Inline Assembler verwendet. In diesem Assembler Code ist ein Label definiert. Da ich diese Funktion an mehreren Stellen aufrufe, kommt es beim Übersetzen zum Fehler:



{standard input}: Assembler messages:
{standard input}:1333: Error: symbol `_loop_label' is already defined
{standard input}:1376: Error: symbol `_loop_label' is already defined
{standard input}:1415: Error: symbol `_loop_label' is already defined
{standard input}:1461: Error: symbol `_loop_label' is already defined
{standard input}:1499: Error: symbol `_loop_label' is already defined
make[3]: *** [drivers/net/dpn/universe_io.o] Error 1


Der Code der Funktion sieht bei mir so aus:


static void inline my_delay(a)
{
__asm__
("_loop_label:\n\t"
".global _loop_label\n\t"
"movl %ecx, (a*1000)\n\t"
"nop\n\t"
"nop\n\t"
"nop\n\t"
"loop _loop_label"
);
}


Wie macht man das da? Danke

Grüße,
Hendrik

7.e.Q
27-09-2006, 06:57
Okay, hab gegoo... gekugelt. :D

Einziges "brauchbares" Ergebnis ist ein Mailinglist Eintrag, wo als Antwort nur
RTFM, Section "output templates" steht. Da steht natürlich nirgends, welches FM man lesen soll. :rolleyes:

OpOs
27-09-2006, 10:27
iss "inline" nich sowas wie'n macro, also textersetzung? dann wird mit jedem "aufruf" der code inklusive label an der entsprechenden stelle eingefuegt und somit mehrfach definiert...

entweder 'ne richtige funktion draus machen oder dafuer sogen, dass das label nur lokal iss...

iss das fuer "as"? kenn mich mit at&t-asm leider nich so aus...

7.e.Q
28-09-2006, 07:28
Das ist für as, ja. Aus Performancegründen möchte ich die Funktion gerne "inline" haben. "inline" bedeutet ja nur, daß die Funktion statt über ein "call" im generierten Maschinencode angesprungen, direkt anstelle des "call" eingefügt wird. Vergrößert zwar die Gesamtgröße der Binary, ist aber bei vielen Aufrufen insgesamt schneller.

Daß das Label dadurch mehrfach definiert wird, versteh ich schon. Die Frage ist halt, wie man das normalerweise macht. Gibt es da ein Konzept, Design Pattern?

Danke

Grüße,
Hendrik

OpOs
28-09-2006, 09:09
was passierten wenn du ".global ..." weglaesst?

7.e.Q
29-09-2006, 08:24
Das gleiche

OpOs
29-09-2006, 09:24
hmm, kann dein problem leider nich reproduzieren, weil sich mein compiler nich um das "inline" schert und trotzdem 'nen call macht...

loesungsmoeglichkeit (unsauber): du rechnest die codelaenge aus und setzt die sprungweite manuell mit "loop $-xxx", das "mov ecx..." musst du dafuer vermutlich hart kodieren, da es mehrere binaere moeglichkeiten fuer diesen befehl gibt (entweder 5 oder 6 byte)

davon abgesehen sehe ich 'nen logischen fehler in deinem code. du must mov und label-definition vertauschen, ansonsten initialisierst du ecx nach jedem loop neu und baust dir damit 'ne endlosschleife wie aus'm lehrbuch...

7.e.Q
04-10-2006, 07:46
@OpOs: Stimmt, du hast Recht, was meinen Denkfehler angeht. Danke.

Also wie baut man normal sowas? Ist doch nix ungewöhnliches oder?

OpOs
05-10-2006, 15:39
meinst du jetzt, wie man eine delay-funktion implementiert?

die baut man normalerweise gar nicht selber, sondern nutzt die funktionen, die die laufzeitbibiothek zur verfuegung stellt. sleep ist dafuer 'n guter kandidat, es gibt auch funktionen, die mit hoeherer genauigkeit arbeiten koennen... haengt von compiler/rtl/platform ab... check mal deine dokus

warum man das nicht macht wie du: du verpulverst rechenleistung und blockierst sinnlos den prozessor. die zeit, die deine cpu mit den zehn- bis hunderttausenden von nops verbringt, koennten andere prozesse oder threads sehr gut mit sinnvolleren aufgaben ausfuellen.
das mag zwar uebertrieben klingen, schliesslich hast du 'nen 3GHz proz mit HT-technologie und dein system ist sowieso nur zu 3% ausgelastet, aber du willst ja auch was lernen, und sauberes und effizientes programmieren gehoeren da dazu ;)
ausserdem ist deine methode ungenau, da sie von taktrate und auslastung abhaengt. der einzige sinnvolle einsatz waere eine kurze pause (von nur ein paar wenigen takten), wenn man portzugriffe mit in/out macht, aber diese schwaeche haben die systeme seit den neunzigern hinter sich gelassen.

falls du aber ein echtes delay selberprogrammieren willst, nutz den timer. schreibe einen timerhandler, der eine variable bei jedem aufruf um 1 dekrementiert. nun musst du in deiner delay-funktion nur die variable hochsetzen und warten, biss sie vom timer wieder auf 0 gesetzt wurde...
achtung: wenn du mit mehreren threads arbeitest, benoetigt jeder thread seine eigene variable.