Bit montážních

29.srpna 2009 od prashant · Komentáře
Soubor pod: Technologie

Po přečtení tohoto článku o zámek zdarma pufrů a vidí využití CAS (srovnání a swap), jsem se cítil jako vysílání kód assembleru, aby učinily totéž. Use case tam byl napsat nativní metodu a volání z Java (zpět na 1,5, při souběžných datových struktur v jazyce Java byly více či méně neexistuje). Bez dalšího povyku, budu uvolnit kód na vás :) . Prvním z nich je pro CAS a druhý je pro výpočet NSD pomocí Eukleidův algoritmus (to lze nalézt na mnoha místech a návody, jak dobře).

Zkompilovat a spustit návod gcc file_name.c ; ./a.out

Porovnejte a odkládací

   # Include 
  # Include 
 / / Výměna - newvalue, comperand je stará / očekávaná hodnota
 / *
  * Funkce vlastně dělá následující věc - pokud je hodnota v * dest se rovná oldvalue pak jej nahradit jiným newvalue ponechat jej beze změny: do všech těchto atomicky
  *
  * Existují dvě možnosti pro návratové hodnoty
  * 1.is počáteční hodnota * dest a ponechat břemeno volání fxn srovnávat je s oldval
  * 2.  to sem a return 0 nebo 1, což by mělo být účinnější
  * * /

 / * Později změnit v makro * /
 int cas (int * dest, int oldvalue, int newvalue) (
	 printf ("(% d,% d,% d)", * dest, oldvalue, newvalue);
	 / * Int cas (int dest, int oldvalue, int newvalue) (* /
	 / * Int cas (int dest, int newvalue, int oldvalue) (* /
	 int vysledek = 1; / * 1 ukazuje, že CAS uspěl a 0 ukazuje, že selhala * /
	 / * Btw je třeba nastavit cc pro vlajky praštit!  * /
	 __asm__ __volatile__ (
			 "Movl% 2,%% eax \ n \ t"
			 "Movl% 3,%% ebx \ n \ t"
			 "Movl% 0,%% ecx \ n \ t"
			 "LOCK \ n \ t"
			 "CMPXCHG%% ebx, (%% ecx) \ n \ t" / * by LOCK být na stejném řádku * /
			 "JZ děje \ n \ t"
			 "Movl $ 0,% 1 \ n \ t"
			 "Hotovo: \ n \ t"
			 : "= M" (dest), "= g" (výsledek)
			 : "G" (oldvalue), "g" (newvalue), "m" (dest)
			 : "% Eax", "% ebx", "ecx", "cc"
			 );
	 printf ("(% d,% d,% d)", * dest, oldvalue, newvalue);
	 return vysledek;
 )

 / * TODO
  * Napsat další asm fxn, které staví nad fxn v cyklu while a dál snažit, pokud uspěje * /

 int main () (
	 int a = 5, b = 6;
	 int * c = (int *) malloc (sizeof (int));
	 * C = 6;
	 / * Int c = 6; * /
	 printf ("% d \ n", CAS (c, b, b));
	 printf ("% d \ n", CAS (c, b, a));
	 printf ("% d \ n", CAS (c, a, a));
	 printf ("% d \ n", CAS (c, b, b));
	 * C = 6;
	 / * C = 5; * /
	 printf ("Změna hodnoty * c k% d \ n", * c);
	 printf ("% d \ n", CAS (c, b, b));
	 printf ("% d \ n", CAS (c, b, a));
	 printf ("% d \ n", CAS (c, a, a));
	 printf ("% d \ n", CAS (c, a, b));
	 printf ("% d \ n", CAS (c, b, a));
	 return 0;
 )

Formátování poznámek - vypadá jako zvýrazňovač wp syntax je přidání Na konci, ignorovat to.

GCD

 # Include 
 int gcd (int a, int b) (
     int výsledek;
     / * Compute největší společný dělitel pomocí Euclid algoritmu * /
     __asm__ __volatile__ ("movl% 1,%% eax;"
                           "Movl% 2,%% ebx;"
                           "CONTD: cmpl $ 0,%% ebx;"
                           "Je pryč;"
                           "Xorl%% edx,%% edx;"
                           "Idivl%% ebx;"
                           "Movl%% ebx,%% eax;"
                           "Movl%% edx,%% ebx;"
                           "Jmp CONTD;"
                           "Hotovo: movl%% eax,% 0;": "= g" (výsledek): "g" (a), "g" (b)
     );

     return vysledek;
 )

 int main () (
     int první, druhé;
     printf ("Zadejte dvě celá čísla:");
     scanf ("% d% d", & první, & druhý);

     printf ("% d GCD &% d je% d \ n", první, druhý, gcd (první, druhá));

     return 0;
 )