Un poco de asamblea

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

Después de leer este artículo sobre el bloqueo de búferes libres y viendo el uso de CAS (compare y de intercambio), me sentí como publicar el código ensamblador a hacer lo mismo. Caso de uso más de 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 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í).

y ejecutar las instrucciones de compilación gcc file_name.c ; ./a.out

Comparar y de intercambio

   # Include 
  # Include 
 / / Cambio - nuevovalor, comperand es viejo / valor esperado
 / *
  * Función de hecho hace lo siguiente - si el valor en dest * es igual a oldValue luego sustituirla por otra nuevovalor no lo cambie: hacer todas estas atómicamente
  *
  * Hay dos opciones para valor de retorno
  * El valor inicial de 1.is * dest y dejar la carga de la llamada FXN compararlo con oldval
  * 2.  hacerlo aquí y devolver 0 o 1, esto debe ser más eficiente
  * * /

 / * Después * convertirla en macro /
 cas int (int * dest, int oldValue, nuevovalor int) (
	 printf ("(% d,% d,% d)", * dest, oldValue, nuevovalor);
	 / * Int cas (dest int, int oldValue, nuevovalor int) (/ *
	 / * Int cas (dest int, int nuevovalor, oldValue int) (/ *
	 int resultado = 1; / * 1 muestra que logró cas y 0 indica que ha fallado * /
	 / * Por cierto necesidad de establecer cc para clobbering bandera!  * /
	 __asm__ __volatile__ (
			 "Movl% 2,% eax% t \ \ n"
			 "Movl% 3,% ebx% t \ \ n"
			 "Movl% 0,% ecx% t \ \ n"
			 "LOCK \ n \ t"
			 "% CMPXCHG% ebx, (ecx%%) \ n \ t" / * debe bloquear estar en la misma línea * /
			 "HECHO jz \ n \ t"
			 "Movl $ 0,% 1 \ n \ t"
			 "HECHO: \ n \ t"
			 : "= M" (dest), "= g" (resultado)
			 : "G" (oldValue), "g" (nuevovalor), "m" (dest)
			 : ""% Eax, "% ebx", "ecx", "cc"
			 );
	 printf ("(% d,% d,% d)", * dest, oldValue, nuevovalor);
	 return resultado;
 )

 / * TODO
  * Escribir otro FXN asm que pone por encima de FXN en un bucle while y seguir tratando a menos que logre * /

 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 ("cambio del 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;
 )

Formato notas - 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 utilizando 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: eax movl%%, 0%;": "= g" (resultado): "g" (a), "g" (b)
     );

     return resultado;
 )

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

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

     return 0;
 )