Zaimplementuj w asemblerze x86-64 rozwiązanie (z drobnymi modyfikacjami) zadania o producencie i konsumencie z buforem cyklicznym omawianego na ćwiczeniach z PW. Wszystkie implementowane procedury powinny przestrzegać konwencji wołania funkcji w języku C. Rozwiązanie powinno składać się z dwóch plików.
Plik dijkstra_semaphore.asm
ma zawierać implementację semafora według
klasycznej definicji Dijkstry. Semafor S jest zmienną typu int32_t
i można na
nim wykonywać dwie operacje: proberen(&S)
i verhogen(&S)
. Plik ten ma
udostępniać te operacje jako dwie funkcje, które mają w C sygnatury:
void proberen(int32_t *);
void verhogen(int32_t *);
Wskazówka: użyj instrukcji xadd.
Plik producer_consumer.asm
ma udostępniać trzy funkcje:
int init(size_t N);
void producer(void);
void consumer(void);
Funkcja init
alokuje bufor cykliczny dla N porcji danych typu int64_t
oraz
inicjuje semafory. Zwraca:
0
, gdy sukces;-1
, gdy N > 231 - 1;-2
, gdy N = 0;-3
, gdy alokacja pamięci się nie powiodła.
Wskazówka: przy porównywaniu liczb ze znakiem korzysta się z instrukcji
je
, jg
, jge
, jl
, jle
, jne
, jng
, jnge
, jnl
, jnle
, a przy
porównywaniu liczb bez znaku – je
, ja
, jae
, jb
, jbe
, jne
, jna
,
jnae
, jnb
, jnbe
.
Wskazówka: o alokowaniu pamięci w programie asemblerowym można poczytać tu http://x86asm.net/articles/memory-allocation-in-linux. Program będzie linkowany ze standardową biblioteką języka C.
Wskazówka: zmienne globalne inicjowane w trakcie wykonywania programu
umieszcza się w sekcji .bss
.
Funkcja producer
realizuje protokół producenta. Aby wyprodukować porcję
danych P
, woła funkcję produce(&P)
o sygnaturze
int produce(int64_t *);
Funkcja produce
zwraca 1, gdy wyprodukowała porcję danych, a 0, gdy nie
wyprodukowała danych i wtedy funkcja producer powinna się zakończyć.
Funkcja consumer
realizuje protokół konsumenta. Aby skonsumować porcję
danych P, woła funkcję consume(P)
o sygnaturze
int consume(int64_t);
Funkcja consume
zwraca 1, gdy oczekuje kolejnych danych, a 0, gdy otrzymana
porcja danych jest ostatnią oczekiwaną i wtedy funkcja consumer powinna się
zakończyć.
Wskazówka: w asemblerze identyfikatory wołanych funkcji, które są
zaimplementowane w innych jednostkach translacji, należy zadeklarować jako
extern
.
Termin oddania: 24 marca 2017, godz. 20.
Pliki należy umieścić w repozytorium SVN w katalogustudenci/ab123456/zadanie2
,
gdzie ab123456
jest identyfikatorem studenta używanym do logowania w
laboratorium komputerowym.