Un poco de ensamblaje

29 de agosto 2009 por prashant
Filed under: la tecnología

Después de leer este artículo acerca de tampones de bloqueo libres y viendo el uso de CAS (comparar e intercambiar), me sentí como publicar el código en ensamblador para hacer lo mismo. El caso de uso sobre lo que había que escribir un método nativo y lo llaman de Java (de nuevo en 1,5, cuando las estructuras de datos concurrentes en Java eran más o menos inexistente). Sin más preámbulos, voy a liberar el código en que :) . En primer lugar es para el CAS y el segundo es para la informática GCD utilizando el algoritmo de Euclides (éste se puede encontrar en muchos lugares y tutoriales, así).

Compila y ejecuta las instrucciones de gcc file_name.c ; ./a.out

Compara y Swap

   # Include 
  # Include 
 / / Cambio - nuevovalor, comperand es viejo / valor esperado
 / *
  * Función que realmente hace lo siguiente - si el valor en * dest es igual a oldValue continuación, sustituirla por otra nuevovalor dejarlo como está: hacer todo esto de forma atómica
  *
  * Hay dos opciones para el valor de retorno
  * El valor inicial de 1.is * dest y dejar la carga de la FXN llamando al compararlo con OLDVAL
  * 2.  hacerlo aquí y devolver 0 o 1, esto debe ser más eficiente
  ** /

 / * Después se convertirá en macro * /
 cas int (int * dest, int oldValue, int nuevo_valor) {
	 printf ("(% d,% d,% d)", * dest, oldValue, newvalue);
	 / * Int CAS (int dest, int oldValue, int nuevo_valor) {* /
	 / * Int CAS (int dest, int nuevovalor, int oldValue) {* /
	 int resultado = 1 ;/ * 1 muestra que el CAS tuvo éxito y 0 muestra que fallaron * /
	 / * Por cierto necesidad de establecer cc para vapulear la bandera!  * /
	 __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" / * debe de cierre puede ser en la misma línea * /
			 "HECHO jz \ n \ t"
			 "Movl $ 0,% 1 \ n \ t"
			 "HECHO: \ n \ t"
			 : "= M" (destino), "= g" (resultado)
			 : "G" (oldValue), "g" (nuevo_valor), "m" (destino)
			 : "% Eax", "% ebx", "ecx", "cc"
			 );
	 printf ("(% d,% d,% d)", * dest, oldValue, newvalue);
	 return resultado;
 }

 / * TODO
  * Escribir otro FXN asm que pone por encima de FXN en un bucle while y seguir intentando si no logra * /

 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 ("valor de cambio de c * a% 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;
 }

Notas de formato - parece marcador wp sintaxis es la adición de al final, ignorar eso.

GCD

 # Include 
 int mcd (int a, int b) {
     int resultado;
     / * Calcular máximo común divisor mediante el algoritmo de Euclides * /
     __asm__ volatile__ __ ("movl% 1,%% eax;"
                           "Movl% 2,%% ebx;"
                           "Cont: CMPL $ 0,%% ebx;"
                           "Je Hecho";
                           "Xorl%% edx,%% edx;"
                           "Idivl%% ebx;"
                           "Movl% ebx%,%% eax;"
                           "Movl%% edx, ebx%%;"
                           "Jmp cont;"
                           "HECHO: movl%% eax, 0%;": "= g" (resultado): "g" (a), "g" (b)
     );

     return resultado;
 }

 int main () {
     int primer segundo,;
     printf ("Introduzca dos enteros:");
     scanf ("% d% d", y en primer lugar, y segundo);

     printf ("El MCD de% d &% d es% d \ n", primero, segundo, mcd (primero, segundo));

     return 0;
 }

Comentarios

    blog alimentado por los comentarios Disqus