Un poco de asamblea

29 de agosto 2009 por Prashant · Comentarios
Filed under: tecnología

Después de leer este artículo acerca de tampones de bloqueo libre y viendo el uso de CAS (compare y swap), me sentí como publicar el código en ensamblador para hacer lo mismo. De casos 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 el que :) . En primer lugar es para el CAS y la segunda es para calcular mcd usando el algoritmo de Euclides (éste se puede encontrar en muchos lugares y tutoriales también).

Compilar y ejecutar las instrucciones de gcc file_name.c ; ./a.out

Comparar y de intercambio

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

 / * Después se transforman 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 nuevo_valor, int oldValue) {* /
	 int resultado = 1 / * 1 muestra que el CAS tuvo éxito y muestra 0 que no * /
	 / * Por cierto necesidad de establecer cc por la bandera de vapulear!  * /
	 __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" / * se debe bloquear en la misma línea * /
			 "HECHO jz \ n \ t"
			 "Movl $ 0,% 1 \ n \ t"
			 "HECHO: \ n \ t"
			 : "= M" (dest), "= g" (resultado)
			 : "G" (oldValue), "g" (nuevo_valor), "m" (dest)
			 : "% 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 ("cambiar el valor 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 con * 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 primero, segundo;
     printf ("Introduzca dos números enteros:");
     scanf ("% d% d", y en primer lugar, y segundo);

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

     return 0;
 }