Малко на събранията

След като прочетете тази статия за свободните буфери заключване и виждат използването на CAS (сравни и суапови), аз се почувствах като публикуване на Асамблеята код, за да направят същото. Използвайте случай там е да пишат на родния метод и го наричат ​​от Java (в 1,5, когато едновременно структури от данни в Java са повече или по-малко не съществуват). Без повече приказки, аз ще отприщи кода върху вас :) . Първият е за КО и втората е за изчисляване на GCD използва алгоритъм на Евклид (това може да се намери на много места и уроци, както и).

Компилирате и изпълнявате инструкциите gcc file_name.c ; ./a.out

Сравнете и суапови

   # Include 
  # Include 
 / / Обмен - newvalue, comperand е стар / очакваната стойност
 / *
  * Функция всъщност прави следното нещо - ако стойността AT * DEST е равна на oldvalue след това да го замените с newvalue друг го остави непроменен: вършим всички тези атомично
  *
  * Има два варианта за връщане стойност
  * 1.is първоначалната стойност на целевите и с напусне тежест на повикващата fxn да го сравни с oldval
  * 2.  го направя тук и да се върне 0 или 1, това трябва да бъде по-ефективно
  ** /

 / * По-късно го промените в макро * /
 INT CAS (Int * DEST, Int oldvalue, вътр newvalue) {
	 ФОРМАТ ("(% d,% D,% г)" * DEST, oldvalue, newvalue),;
	 / * Int CAS (INT DEST, Int oldvalue, вътр newvalue) {* /
	 / * Int CAS (INT DEST, Int newvalue, вътр oldvalue) {* /
	 Int резултат = 1 ;/ * 1 показва, че CAS успели и 0 показва, че не успя * /
	 / * Между другото трябва да зададете CC за знаме clobbering,,!  * /
	 volatile__ __asm__ __ (
			 "Movl 2%,% EAX \ n \ т"
			 "Movl% 3,% ebx \ n \ т"
			 "Movl% 0% ECX \ n \ т"
			 "LOCK \ n \ т"
			 "CMPXCHG ebx%, (% ECX) \ n \ т" / * следва да заключите е на същия ред * /
			 "JZ \ n \ т"
			 "Movl $ 0,% 1 \ n \ т"
			 "Готово: \ n \ т"
			 : "= M" (DEST), "= G" (резултат)
			 : "G" (oldvalue), "ж" (newvalue), "M" (DEST)
			 : "EAX%",% ebx ", - ECX", "CC"
			 );
	 ФОРМАТ ("(% d,% D,% г)" * DEST, oldvalue, newvalue),;
	 върне резултат;
 }

 / * TODO
  * Напише друга ASM fxn, която поставя над fxn в последно време контур и продължаваме да опитваме, освен ако не успее * /

 INT главната () {
	 Int A = 5, B = 6;
	 и Int * C = (INT *) изчистване (sizeof (INT));
	 * C = 6;
	 / * Int C = 6; * /
	 ФОРМАТ ("% г \ n", CAS (C, B, б));
	 ФОРМАТ ("% г \ n", CAS (C, B, а));
	 ФОРМАТ ("% D \ n", CAS (C, A, а));
	 ФОРМАТ ("% г \ n", CAS (C, B, б));
	 * C = 6;
	 / * C = 5; * /
	 ФОРМАТ ("смяна на стойността на * C% г \ n", * в);
	 ФОРМАТ ("% г \ n", CAS (C, B, б));
	 ФОРМАТ ("% г \ n", CAS (C, B, а));
	 ФОРМАТ ("% D \ n", CAS (C, A, а));
	 ФОРМАТ ("% г \ n", CAS (C, A, б));
	 ФОРМАТ ("% г \ n", CAS (C, B, а));
	 връщането на 0;
 }

Форматиране на бележки - изглежда като маркер WP синтаксис е добавянето в края на краищата, игнорирайте.

GCD

 # Include 
 INT GCD (INT един, вътр б) {
     Int резултат;
     / * Compute-големия общ делител, използвайки алгоритъм на Евклид * /
     volatile__ __asm__ __ ("movl% 1,% EAX;"
                           "Movl 2%,% ebx;"
                           "CONTD: cmpl $ 0,%% ebx;"
                           "Je свърши;"
                           "Xorl% EDX,% EDX;"
                           "Idivl% ebx;"
                           "Movl ebx%,% EAX;"
                           "Movl% EDX,% ebx;"
                           "JMP CONTD,;"
                           "Готово: movl% EAX, 0%;": "= G" (резултат): "ж" (а), "G" (б)
     );

     върне резултат;
 }

 INT главната () {
     вътр първо, второ;
     ФОРМАТ ("Въведете две цели числа:");
     scanf ("% г% D", и на първо място, и втория);

     ФОРМАТ ("GCD% D &% D% D \ n", първо, второ, GCD (първо, второ));

     връщането на 0;
 }