Um pouco de montagem

29 de agosto de 2009 por Prashant · Comentários
Arquivado em: tecnologia

Depois de ler este artigo sobre o bloqueio de buffers livre e vendo o uso de CAS (compare e swap), eu senti como postar o código assembly para fazer o mesmo. Use caso ali era escrever um método nativo e chamá-lo de Java (de volta na versão 1.5, quando as estruturas de dados simultâneas em Java eram mais ou menos inexistente). Sem mais delongas, vou liberar o código para você :) . O primeiro é para a CAS ea segunda é para a computação GCD usando o algoritmo de Euclides (este pode ser encontrada em muitos lugares e tutoriais também).

Compilar e executar instruções gcc file_name.c ; ./a.out

Compare e Swap

   # Include 
  # Include 
 / / Troca - newvalue, comperand é velho / valor esperado
 / *
  * Função realmente faz o seguinte - se o valor em dest * é igual a OldValue então substituí-lo por outro newvalue deixar inalterado: fazer todas estas atomicamente
  *
  * Existem duas opções para o valor de retorno
  * O valor inicial de 1.is dest * e deixar o ônus da chamada fxn compará-lo com oldval
  * 2.  fazê-lo por aqui e retornar 0 ou 1, isto deveria ser mais eficiente
  * * /

 / * Depois transformá-lo em macro * /
 cas int (int * dest, int OldValue, newvalue int) (
	 printf ("(% d,% d,% d)" * dest, OldValue newvalue);
	 / * Int cas dest (int, int OldValue, newvalue int) (/ *
	 / * Int cas dest (int, int newvalue, OldValue int) (/ *
	 int resultado = 1 / * 1 mostra que conseguiu cas e 0 indica que ele falhou * /
	 / * Btw necessidade de definir cc para clobbering bandeira!  * /
	 __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" / * LOCK deve estar na mesma linha * /
			 "Jz FEITO \ n \ t"
			 "Movl $ 0,% 1 \ n \ t"
			 "DONE: t \ n"
			 : "=" M "dest () = g (resultado)
			 "G" (OldValue), "g" (newvalue), "m" (DEST)
			 : "% Eax,% ebx", "ecx", "cc"
			 );
	 printf ("(% d,% d,% d)" * dest, OldValue newvalue);
	 resultado de retorno;
 )

 / * TODO
  * Escrever outro fxn asm que coloca acima fxn em um loop while e tentando manter, a menos que sucede * /

 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 troca de 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;
 )

Formatação notas - parece highlighter sintaxe wp está adicionando no fim, ignore isso.

GCD

 # Include 
 int mdc (int a, int b) (
     int resultado;
     / * Compute Máximo Divisor Comum usando * Algoritmo de Euclides /
     __asm__ __volatile__ ("movl% 1,% eax%;"
                           "Movl% 2,% ebx%;"
                           "Cont.: cmpl $ 0,% ebx%;"
                           "Je feito;"
                           "Edx xorl%%,% edx%;"
                           "Ebx% idivl%;"
                           "Ebx movl%%,% eax%;"
                           "Movl% edx% ebx%%;"
                           "Jmp cont.";
                           "DONE:% eax movl%, 0%;": "= g (resultado):" g "(a)," g "(b)
     );

     resultado de retorno;
 )

 int main () (
     int primeiro, o segundo;
     printf ("Digite dois inteiros:");
     scanf ("% d% d", e primeiro e segundo);

     printf ("GCD% de d &% d é% d \ n", primeira, segunda, mdc (primeiro, segundo));

     return 0;
 )