Un pic de asamblare

29 august 2009 de Prashant
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;
 }

Comentarii

    comentarii blog powered by Disqus