ARCHITEKTURA SYSTEMÓW KOMPUTEROWYCH: Instrukcja do laboratorium 4, (2x2h) Opracowanie i prowadzenie: dr inż. Ignacy Pardyka, Uniwersytet Jana Kochanowskiego w Kielcach Temat: Architektura MIPS: wywołanie funkcji, stos, złożone struktury danych symulator: MARS
1. Wstęp
W ramach niniejszego laboratorium, najpierw poznajemy mechanizm wywoływania funkcji, stosowany w architekturze MIPS. Aby zrozumieć ten mechanizm, musimy poznać i zrozumieć pojęcie ramki stosu. Szczególne miejsce, w programowaniu komputerów, zajmują algorytmy rekurencyjne, dlatego ważne jest by rozumieć, w jaki sposób należy prawidłowo organizować program, w którym występują rekurencyjne wywołania funkcji. W języku asemblera stos odgrywa ważną rolę. Poznamy też zasadę przechowywania i przetwarzania złożonych struktur danych.
2. Instrukcje wywołania funkcji i powrotu
2.1. W architekturze MIPS, na liście instrukcji widzimy dwie instrukcje dotyczące funkcji:
a) instrukcję jal, która określa operację przekazania sterowania do funkcji (ze śladem); instrukcja ta nakazuje, aby procesor, zanim przekaże sterowanie do wskazanej funkcji (wykonując operację skoku), zapamiętał w rejestrze $ra adres instrukcji, występującej w programie tuż za instrukcją jal (czyli adres powrotu z funkcji do miejsca wywołania).
b) instrukcję jr, określającą operację powrotu z funkcji do programu, który ją wywołał; instrukcja ta, faktycznie, nakazuje procesorowi wykonanie operacji skoku bezwarunkowego pod adres, który aktualnie jest w rejestrze $ra (return address).
2.2. Zadanie 1
a) Wprowadzić następujący program .data
stringl: .asciiz "Hello world!\n"
string2: .asciiz "Drugi napis\n"
.text
# drukuj pierwszy łańcuch
main: la $a0, stringl
li $v0, 4
# teraz wywołać funkcję function() bez argumentów.
# stosujemy instrukcję jal, która nakazuje
# zapamiętać w $ra adres instrukcji występującej
# tuż za jal, a następnie wykonać skok
# do pierwszej instrukcji w funkcji
# $a0 zawiera wskaźnik do pierwszego z łańcuchów
# więc drukować go
jal function li $v0, 4
li $v0, 10 # exit
# Ta funkcja jest wywoływana z main(). Drukuje łańcuch i zwraca sterowanie do wywołującego, function: la $a0, string2
li $v0, 4
syscall # drukuj łańcuch
jr $ra
# powrót do instrukcji wskazywanej przez $ra