Ένα κομμάτι της συναρμολόγησης

29 Αυγούστου 2009 από Prashant · Σχόλια
Filed under: τεχνολογία

Μετά την ανάγνωση αυτού του άρθρου για την κλειδαριά χωρίς προσκρουστήρες και βλέποντας τη χρήση του CAS (συγκρίνετε και swap), ένιωσα σαν απόσπαση τον κωδικό συνέλευση για να κάνουν το ίδιο. Χρησιμοποιήστε περίπτωση άνω ήταν εκεί για να γράψω ένα εγγενές μέθοδο και το ονομάσουμε από Java (πίσω στο 1,5, όταν η ταυτόχρονη δομές δεδομένων σε Java ήταν περισσότερο ή λιγότερο δεν υπάρχουν). Χωρίς άλλη καθυστέρηση, θα απελευθερώσει τον κώδικα επάνω σε σας :) . Πρώτη είναι για το CAS και το δεύτερο είναι για τον υπολογισμό GCD χρησιμοποιώντας αλγόριθμο του Ευκλείδη (αυτό μπορεί να βρεθεί σε πολλά μέρη και σεμινάρια καθώς επίσης).

Μεταγλωττίστε και εκτελέστε τις οδηγίες gcc file_name.c ; ./a.out

Συγκρίνετε και Εναλλαγ

   # Include 
  # Include 
 / / Ανταλλαγή - newvalue, comperand είναι παλιά / αναμενόμενη αξία
 / *
  * Λειτουργία πραγματικά κάνει τα εξής πράγμα - αν η τιμή στα dest * είναι ίσο με oldvalue στη συνέχεια να την αντικαταστήσει με άλλο newvalue αφήσει αμετάβλητα: κάνω όλα αυτά atomically
  *
  * Υπάρχουν δύο επιλογές για την τιμή επιστροφής
  * 1.is αρχική αξία του dest * και αφήνουν το βάρος της καλώντας fxn να το συγκρίνουμε με oldval
  * 2.  το κάνει εδώ και επιστρέφει 0 ή 1, αυτό θα πρέπει να είναι πιο αποτελεσματική
  * * /

 / * Το αλλάξετε αργότερα σε μακροοικονομικό * /
 int cas (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 αποτέλεσμα = 1? / * 1 δείχνει ότι cas κατάφερε και 0 προκύπτει ότι αυτή παραβίασε * /
	 / * Btw ανάγκη να καθοριστούν cc για clobbering σημαία!  * /
	 __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 να βρίσκονται στην ίδια γραμμή * /
			 "JZ ΕΓΙΝΕ \ n \ t"
			 "Movl $ 0,% 1 \ n \ t"
			 "ΕΓΙΝΕ: \ t \ n"
			 : "= M" (DEST), "= g" (αποτέλεσμα)
			 : "G" (oldvalue), το "γ" (newvalue), "m" (DEST)
			 : "" EAX%, "ebx%", "ECx", "cc"
			 )?
	 printf ("(% d,% d,% d)", dest *, oldvalue, newvalue)?
	 αποτέλεσμα την επιστροφή?
 )

 / * TODO
  * Γράψω ένα άλλο fxn asm που βάζει πάνω από fxn σε έναν βρόχο, ενώ συνεχίζουμε να προσπαθούμε και αν δεν καταφέρει * /

 int main () (
	 int a = 5, b = 6?
	 int * c = (int *) malloc (sizeof (int))?
	 * C = 6?
	 / * Int c = 6? * /
	 printf ("% d \ n", cas (γ, β, β))?
	 printf ("% d \ n", cas (γ, β, α))?
	 printf ("% d \ n", cas (γ, α, α))?
	 printf ("% d \ n", cas (γ, β, β))?
	 * C = 6?
	 / C * = 5? * /
	 printf ("μεταβαλλόμενη αξία του γ * σε% d \ n", * γ)?
	 printf ("% d \ n", cas (γ, β, β))?
	 printf ("% d \ n", cas (γ, β, α))?
	 printf ("% d \ n", cas (γ, α, α))?
	 printf ("% d \ n", cas (γ, α, β))?
	 printf ("% d \ n", cas (γ, β, α))?
	 επιστροφή 0?
 )

Μορφοποίηση σημειώσεων - φαίνεται σαν highlighter σύνταξη wp είναι η προσθήκη στο τέλος, να την αποκλείσουμε.

GCD

 # Include 
 int gcd (int a, int b) (
     int αποτέλεσμα?
     / * Υπολογισμός Μέγιστος Κοινός Divisor χρησιμοποιώντας τον αλγόριθμο του Ευκλείδη * /
     __asm__ __volatile__ ("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" (α), "g" (β)
     )?

     αποτέλεσμα την επιστροφή?
 )

 int main () (
     int πρώτο, το δεύτερο?
     printf ("Δώστε δύο ακέραιους αριθμούς:")?
     scanf ("% d% d", & αφενός, και η δεύτερη)?

     printf ("GCD των% d & d% είναι% d \ n", πρώτο, δεύτερο, GCD (πρώτη, δεύτερη))?

     επιστροφή 0?
 )