Un pic de asamblare

29 august 2009 de Prashant · Comentarii
Filed under: tehnologie

După ce aţi citit acest articol despre buffer gratuite de blocare şi de a vedea de utilizare a CAS (comparati si swap), m-am simtit ca postarea codul de asamblare să facă acelaşi lucru. Utilizaţi caz acolo a fost de a scrie o metodă de nativ şi să-l de la Java (înapoi la 1,5, atunci când structurile de concurente de date în Java au fost mai mult sau mai puţin inexistente). Fără alte introduceri, voi dezlănţui codul de pe tine :) . Primul este pentru CAS şi al doilea este pentru GCD de calcul folosind algoritmul lui Euclid (acesta poate fi găsit în multe locuri şi tutoriale precum şi).

Compila si rula instrucţiuni de gcc file_name.c ; ./a.out

Compară şi Swap

   # Include 
  # Include 
 / / De schimb - NewValue, comperand este vechi / aşteptat valoare
 / *
  * Funcţie face de fapt următorul lucru - în cazul în care valoarea de la * dest este egal cu oldvalue apoi înlocuiţi-l cu NewValue altfel se lasa neschimbat: nu toate acestea atomic
  *
  * Există două opţiuni pentru valoarea de returnare
  * Valoarea iniţială a 1.is * dest şi lasă povara fxn de asteptare pentru a se compara cu oldval
  * 2.  face aici şi pentru a reveni 0 sau 1, acest lucru ar trebui să fie mai eficientă
  ** /

 / * Schimbă mai târziu, în macro * /
 CAS int (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) {* /
	 Rezultatul int = 1 ;/ * 1 arată că CAS reuşit şi 0 arată că a eşuat * /
	 / * BTW nevoie pentru a seta CC pentru pavilion platesti!  * /
	 __asm__ __ volatile__ (
			 "Movl% 2,%% eax \ n \ t"
			 "Movl% 3,%% ebx \ n \ t"
			 "0% movl,%% ecx \ n \ t"
			 "LOCK \ n \ t"
			 "CMPXCHG% ebx%, (%% ecx) \ n \ t" / * ar trebui să fie LOCK de pe aceeaşi linie * /
			 "JZ DONE \ n \ t"
			 "Movl $ 0, 1% \ n \ t"
			 "DONE: \ n \ t"
			 : "M =" (destinatie), "= g" (rezultat)
			 : "G" (oldvalue), "G" (NewValue), "M" (destinatie)
			 : "% EAX", "% ebx", "ecx", "cc"
			 );
	 printf ("(% d,% d,% d)", * dest, oldvalue, NewValue);
	 a reveni rezultat;
 }

 / * TODO
  * A scrie un alt fxn al AŞM, care pune mai sus, fxn într-o buclă în timp ce încerca şi să păstreze excepţia cazului în care aceasta reuşeşte * /

 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 ("valoare schimbarea de la C *% 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;
 }

Note de formatare - se pare ca evidenţiere Sintaxa WP este adăugarea în final, că ignora.

GCD

 # Include 
 int cmmdc (int a, int b) {
     int rezultat;
     / * Compute mai mare divizor comun folosind algoritmul lui Euclid * /
     __ volatile__ __asm__ ("movl% 1,%% eax;"
                           "Movl% 2,%,% ebx;"
                           "CONTD: cmpl $ 0,%% ebx;"
                           "Je făcut;"
                           "Xorl%% EDX, EDX%%;"
                           "Idivl%% ebx;"
                           "Movl% ebx%,%% eax;"
                           "Movl%% EDX,% ebx%;"
                           "JMP CONTD;"
                           "DONE: movl%% EAX,% 0;": "= g" (rezultat): "g" (a), "G" (b)
     );

     a reveni rezultat;
 }

 int main () {
     int prima secundă,;
     printf ("Introduceti doua numere:");
     scanf ("% d% d", şi în primul rând, şi al doilea);

     printf ("% d de GCD &% d este% d \ n", prima, a doua, cmmdc (prima, a doua));

     return 0;
 }