Μετατροπή χαρακτήρων ASCII σε ακέραιο αριθµό (atoi) & Άνοιγµα αρχείου µέσα από τo QtSPIM, διάβασµα, και αποθήκευση του περιεχοµένου του στη µνήµη ( ιάλεξη 3) ιδάσκων: Γιώργος Ζάγγουλος Email: zaggoulos.george@ucy.ac.cy 1
Μετατροπή ASCII σε εκαδικό αριθµό «431» -> 431 «431» = 0x34 0x33 0x31 431 = 4*100 + 3*10 + 1 Πως θα καταλήξω στο 400? Πολλαπλασιάζοντας επαναληπτικά το 4 µε το 10 δύο φορές Πως θα καταλήξω στο 30? Πολλαπλασιάζοντας επαναληπτικά το 3 µε το 10 µία φορά Πως θα καταλήξω στο 1? Πολλαπλασιάζοντας επαναληπτικά το 1 µηδέν φορές 2
Αλγόριθµος 3
Μετατροπή χαρακτήρων ASCII σε ακέραιο Ο πιο κάτω κώδικας µετατρέπει το 2 ο όρισµα που εισάγεται από τo Run Parameters του QtSpim σε integer και τον εκτυπώνει στην οθόνη. main: 1. bne $a0, 2, error1# έλεγχος αριθµού ορισµάτων 2. li $t3, 10 # constant 10 for the multiplications 3. move $s0, $zero # αρχικοποίηση $s0 µε µηδέν 4. lw $t0, 4($a1) # θέση µνήµης ($α1) + 4 κρατά την # διεύθυνση του 2 ου ορίσµατος (αριθµού) atoi: 5. lb $s1, ($t0) # $s1 παίρνει το σηµαντικότερο ψηφίο 6. beq $s1, 0, done # ελέγχει αν είναι null 7. sub $s1, $s1, 0x30 # αφαιρεί 0x30 (48) για να βρει # την τιµή του 8. mul $s0, $s0, $t3 # πολλαπλασιάζει µε τo 10 9. add $s0, $s0, $s1 # προσθέτει το νέο ψηφίο 10. addi $t0, $t0, 1 # αυξάνει το δείκτη της µνήµης 11. b atoi # συνεχίζει από την αρχή της atoi 4
Μετατροπή χαρακτήρων ASCII σε ακέραιο error1: 12. li $v0, 4 13. la $a0, invalid_arg # εκτύπωση του µηνύµατος 14. syscall 15. b exit_p done: 16. li $v0, 1 17. move $a0, $s0 # εκτύπωση του αριθµού (integer) 18. syscall exit_p: 19. li $v0, 10 20. syscall # τέλος προγράµµατος 5
ιάβασµα Αρχείου από το SPIM Οι διαδικασίες που αφορούν προσπέλαση αρχείων γίνονται µε την βοήθεια system calls. ΠΡΟΣΟΧΗ! Στο εγχειρίδιο του SPIM που έχετε, λανθασµένα αναφέρει ότι οι τιµές επιστροφής (result) των system calls προσπέλασης αρχείων βρίσκονται στον $a0. Στην πραγµατικότητα οι τιµές αυτές τοποθετούνται µετά την κλήση τους στον $v0. 6
Άνοιγµα $v0 = 13 Πράξεις µε αρχεία $a0 = full path του αρχείου (string) $a1 = flags, $a2 = UNIX octal file mode (0644 for rw-r--r--) When done then >>> $v0 = file descriptor (not $a0) Ανάγνωση $v0 = 14 $a0 = file descriptor, $a1 = buffer address, $a2 = amount of bytes to read A44 When done then >>>>> $v0 = amount of data in buffer from file (-1 = error, 0 = end of file) 7
Πράξεις µε αρχεία (συν.) Εγγραφή $v0 = 15 $a0 = file descriptor, $a1 = buffer address, $a2 = amount to write in bytes When done then >>>>>> $v0 = amount of data in buffer to file (-1 = error, 0 = end of file) Κλείσιµο $v0 = 16 $a0 = file descriptor A44 8
Flags Flags and Modes Read = 0x0, Write = 0x1, Read/Write = 0x2 Modes 0x0(User)(Group)(Other) Σε κάθε NIBBLE (4 bits) χρησιµοποιούµε τα πρώτα LSBits για να «Σηµειώσουµε» µε 1 την ιδιότητα. Στην πρώτη θέση του NIBBLE ορίζεται η «Εκτέλεση», ακολούθως η «Εγγραφή» και ακολούθως η «Ανάγνωση». Αν δηλαδή για τον ιδιοκτήτη του αρχείου θέλουµε ανάγνωσηεγγραφή αλλά ΌΧΙ εκτέλεση και για το GROUP και ΟTHERS θέλουµε µόνο ανάγνωση τότε: li $a2 0x0644 δηλαδή $a2 = 0000..0000 0110 0100 0100 9
Άνοιγµα Αρχείου από το SPIM # ====== OPEN.txt FILE =========== 1. li $v0, 13 #syscall 13 to open file 2. la $a0, filename #pass to a0 the filename 3. li $a1, 0 #flags=0 (read only) 4. li $a2,0400 #mode (user only, read only ) 5. syscall 6. beq $v0, -1, no_file #check if file has open #flags: 0=read, 1=write, 2=read/write #mode (permissions): 7=111 = read/write/execute # ==== READ & SAVE txt file context in memory == 7. move $a0, $v0 #a0 = file descriptor 8. la $a1, static_mem #a1 = buffer (memory pointer) 9. li $a2, 1#a2 = number of bytes to be read (length) #a2 = 1 in order to read character by char. 10
ιάβασµα Αρχείου από το SPIM next_charac: 10. li $v0, 14 # SYSCALL 14 TO READ FILE 11. syscall 12. beq $a0, 0, read_error # IF $a0=0, ERROR 13. lb $s2, ($a1) # LOAD 1 BYTE FROM MEMORY ($a1) 14. beq $s2, 0x23, close_file # CHECK FOR #" TO CLOSE FILE 15. addi $a1, $a1, 1 # MOVE POINTER TO MEMORY 16. addi $t3, $t3, 1 # TEXT FILE LENGTH COUNTER 17. b next_charac # GO BACK TO READ NEW CHARACTER # =========== CLOSE TEXT FILE =========== close_file: 18. li $v0, 16 # SYSCALL 16 TO CLOSE FILE 19. syscall 11
Μαθησιακοί Στόχοι 4 ης Εβδοµάδας Μετατροπή χαρακτήρων ASCII σε αριθµό Άνοιγµα αρχείου (.txt) από το Spim ιάβασµα αρχείου και µεταφορά του περιεχοµένου στη µνήµη. Επεξεργασία περιεχοµένου (χαρακτήρες/ αριθµοί) 12