δλδ αν λεει προσημασμενος αριθμος x 8βιτ και θελω πχ να βρω το 5*χ δλδ 16 βιτ αποτελεσμα κοιτω αν χ θετικος η αρνητικος και αν ειναι αρνητικος τον κανω θετικο και μετα lsl και αν εχω carry αυξανω το result_high?? γτ δεν μπορω να καταλαβω πως οταν τ κανω ολα αυτα δεν χανεται τ προσημο του χ...
Ok... Πάρε σαν παράδειγμα τον αριθμό -127(=10000001):
Εφόσον το αποτέλεσμά σου θα είναι -πιθανόν- 16 bit, βάλε τον θετικό του (με neg=01111111) στο result_L εξ' αρχής...
Το 5x=4x+x...Εφόσον σου λέει να μη χρησιμοποιήσεις mul, δουλεύεις με lsl... Κάνεις lsl, άρα 11111110 και C=0, ξανά lsl και τώρα C=1=> αυξάνεις το result_L (inc).
Τώρα έχεις τον αριθμό 00000001 11111100 (το πρώτο στο high, το 2ο στο low)...
Προσθέτεις σ' αυτό το x (την τιμή που είχε μόλις τον έκανες θετικό=01111111) και το αποτέλεσμά σου είναι τώρα 00000010 01111011 (δηλαδή το 63 στο δεκαδικό).
Για να γίνει αυτό -635 που θα έπρεπε να βγαίνει, κάνεις com στο result_H και neg στο result_L.... Οπότε και έχεις 11111101 10000101 που είναι το -635...
Καν' το με το χέρι για να το καταλάβεις (ελπίζω να μην έχω κάποιο λάθος, λόγω βιασύνης)...
Φυσικά μπορείς να το κάνεις με διάφορους τρόπους (μιας και υπάρχει μεγάλη γκάμα εντολών), αλλά αυτός είναι ένας (σίγουρα όχι ο βέλτιστος βέβαια)!
σε ευχαριστω παρα πολυ!το καταλαβα πληρως
Μόλις είδα το σχετικό post. Από όσο γνωρίζω εγώ, το θέμα έχει ως εξής:
Ο AVR γενικά έχει εντολές πράξεων του σε συμπλήρωμα του 2. Αυτό σημαίνει ότι αν ο αριθμός σου είναι θετικός, δεν χρειάζεται καμία άλλη κίνηση.
Μπορείς να πολλαπλασιάσεις *2 με lsl στο low_byte και αμέσως rol High_byte για το κρατούμενο.
Η διαίρεση /2 αντίστοιχα γίνεται με lsr High_byte και ror Low_byte.
Αν όμως ο αριθμός είναι αρνητικός, το πρόβλημα είναι ότι η διαίρεση δεν λειτουργεί.
Για τον πολ/σμο κ πάλι δε χρειάζεται να κάνεις τίποτα, διότι λειτουργεί κανονικά και πράττεις όπως παραπάνω.
Για την διαίρεση, το θέμα έχει ως εξής:
Ο AVR ναι μεν δεν κάνει διαίρεση με την εντολή lsr για αρνητικούς συμπληρώματος του 2, αλλά κάνει για αρνητικούς συμπληρώματος του 1. Οπότε εσύ πρέπει να πάρεις συμπλήρωμα του 2, ώστε να έχεις το μέτρο του αριθμού, έπειτα συμπλήρωμα του 1, να κάνεις την διαίρεση και τέλος να επαναφέρεις το αποτέλεσμα σε συμπλήρωμα του 2. Αυτό γίνεται ας πούμε ως εξής:
Έστω αρχικά ότι έχεις έναν 8 bit αριθμό και θέλεις να τον κάνεις /2. Τον αριθμό τον κρατάς αρχικά στο number_L, ενώ έχεις κ έναν καταχωρητή number_dek, για το δεκαδικό που θα προκύψει.
sbrc number_L,7 //έλεγχος προσήμου
rjmp negative // αν ειναι 1, είναι αρνητικός
lsr number_L // αλλιώς θετικός και διαιρείς κανονικά
ror number_dek
rjmp end
negative: // είναι αρνητικός
neg number_L //παίρνεις συμπλήρωμα του 2, ώστε να έχεις το μέτρο
com number_L //κ συμπλήρωμα του 1 για να πάρεις τον αρνητικό σε μορφή συμπληρώματος 1
lsr number_L // κάνεις διαίρεση
ror number_dek
com number_L // κ επαναφέρεις σε συμπλήρωμα του 2 το αποτέλεσμα
neg_number_L
rjmp end
Έτσι νομίζω είναι κ γενικά δεν είχα ποτέ πρόβλημα με την συγκεκριμένη υλοποίηση. Αν τώρα κάποιος δε συμφωνεί, ας πει άποψη να το δούμε το θέμα πιο καλά
