Um pouco de montagem

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

Depois de ler este artigo sobre buffers livre e bloqueio de ver o uso de CAS (compare e swap), eu senti como postar o código assembly para fazer o mesmo. Caso de uso sobre o que havia para escrever um método nativo e chamá-lo de Java (de volta em 1.5, quando as estruturas de dados simultâneas em Java eram mais ou menos não existe). Sem mais delongas, eu vou liberar o código para você :) . Primeiro é a CAS ea segunda é para a computação GCD usando o algoritmo de Euclides (este pode ser encontrado 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 a coisa seguinte - se o valor no * dest é igual a oldvalue então substituí-lo por newvalue mais deixá-lo inalterado: fazer todas estas atomicamente
  *
  * Há duas opções para o valor de retorno
  * O valor inicial de 1.is * dest e deixar o ônus de chamar fxn compará-lo com oldval
  * 2.  fazê-lo por aqui e retornar 0 ou 1, isto deve ser mais eficiente
  * * /

 / * Depois transformá-lo em 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) {/ *
	 int result = 1; / * 1 mostra que cas sucedido e 0 mostra que falhou * /
	 / * Btw precisa definir cc para sobrepor bandeira!  * /
	 __volatile__ __asm__ (
			 "Movl% 2,%% eax \ n \ t"
			 "Movl% 3,%% ebx \ n \ t"
			 "0% movl,%% ecx \ n \ t"
			 "LOCK \ n \ t"
			 "Cmpxchg ebx%%, (%% ecx) \ n \ t" / * deve bloquear ser na mesma linha * /
			 "Jz DONE \ n \ t"
			 "Movl $ 0,% 1 \ n \ t"
			 "DONE: \ n \ t"
			 : "= 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 continuar tentando, 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 ("mudando o 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 formatação - parece highlighter de sintaxe wp está adicionando no final, ignore isso.

GCD

 # Include 
 int mdc (int a, int b) {
     int resultado;
     / * Calcula o máximo divisor comum usando * Algoritmo de Euclides /
     __volatile__ __asm__ ("movl% 1,%% eax;"
                           "Movl% 2,%% ebx;"
                           "Contd: $ cmpl 0, ebx%%;"
                           "Je FEITO";
                           "Xorl%% edx,% edx%;"
                           "Idivl%% ebx;"
                           "Ebx movl%%,%% eax;"
                           "Movl% edx%, ebx%%;"
                           "Jmp contd;"
                           "DONE: movl% eax%, 0%;": "= g" (resultado): "g" (a), "g" (b)
     );

     resultado de retorno;
 }

 int main () {
     int primeiro, o segundo;
     printf ("Entre com dois inteiros:");
     scanf ("% d% d", e em primeiro lugar, e segundo);

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

     return 0;
 }