Малко на събранията
След като прочетете тази статия за свободните буфери заключване и виждат използването на 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
# IncludeINT 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; }



































