Przyk ad debugger
This presentation is the property of its rightful owner.
Sponsored Links
1 / 7

Przykład - Debugger PowerPoint PPT Presentation


  • 83 Views
  • Uploaded on
  • Presentation posted in: General

Przykład - Debugger. Język pewnego procesora zawiera następujące instrukcje: MOV l, rl:=r ADD l, rl := l + r SUB l, rl := l - r JMP instrskok bezwarunkowy IFZERO r, instrskok jeśli r - 0 IFMINUS r, instrskok jeśli r < 0

Download Presentation

Przykład - Debugger

An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -

Presentation Transcript


Przyk ad debugger

Przykład - Debugger

Język pewnego procesora zawiera następujące instrukcje:

MOV l, rl:=r

ADD l, rl := l + r

SUB l, rl := l - r

JMP instrskok bezwarunkowy

IFZERO r, instrskok jeśli r - 0

IFMINUS r, instrskok jeśli r < 0

"r" oznacza jedną z następujacych postaci wartości:

stala

rejestrwartosc zapisana w rejestrze

[rejestr+stała]wartość w pamięci pod adresem

(wartość w rejestrze + stała)

adreswartość w pamięci pod podanym adresem

"l" oznacza miejsce na wynik; pierwsza postać nie jest dopuszczalna, pozostałe określaja miejsce, gdzie ma się znależć wynik.

ZADANIE: wykonać model, projekt i zapisac w Smalltalku system klas będący częścią systemu wspomagającego uruchamianie i testowanie programu na maszynie z danym językiem.

Nasz system powinien uwzględniać pułapki (breakpoint) zwykłe i

warunkowe.

Musi być możliwe wykonanie programu począwszy od danej instrukcji aż do końca lub do momentu przerwania przez pułapkę.

Musi być możliwość "cofania" programu od instrukcji na ktorej ostatnio się zatrzymaliśmy, do momentu spotkania pułapki lub instrukcji, od której w ogóle rozpoczęliśmy wykonanie programu.


Klasy

Zmienne globalne

KLASY

Pamięć - zmienna bliżej nieznanej klasy

Dostępne operacje :

at: adres

at: adres put: wartość

gdzie adres - l. całkowita

Rejestry - zmienna bliżej nieznanej klasy

Dostepne operacje:

at: rejestr

at: adres put: wartość

gdzie rejestr - obiekt klasy Rejestr.

Rejestr

nic o niej nie wiemy, ma tylko istnieć

Musimy w jakis sposób reprezentować wartości "r" i "l", tak, aby instrukcja nie musiała martwić się o to, jakiej postaci ma argumenty.

Propozycja:

Argument - podklasa klasy Object

atrybuty: ??

operacje:

dajWartośćzwraca wartość argumentu

wstawWartość: wwstawia wartość pod właściwy adres pamięci lub do właściwego rejestru

Widać, że operacje są istotnie zależne od rodzaju argumentu -

dziedziczenie!


Przyk ad debugger

Hierarchia klas:

Argument (atrybuty: brak) - klasa abstrakcyjna

ArgStała (atr: wartość - przechowuje liczbę całk.)

ArgRejestr (atr: rej - przechowuje obiekt typu Rejestr)

ArgRejestrStała(atr: rej, wartość)

ArgAdres (atr: adr - przechowuje liczbę)

Object subclass: #Argument

instanceVariableNames: ''

classVariableNames: ''

poolDictionaries: ''

dajWartość

" Zaimplementowana w podklasach"

wstawWartość: w

" Zaimplementowana w podklasach"

Argument subclass: #ArgStała

instanceVariableNames: ' wartość'

classVariableNames: ''

poolDictionaries:''

wartość: w" do inicjalizacji"

wartość := w

dajWartość

^wartość

wstawWartość: w

self error: "Nie da się"


Przyk ad debugger

Argument subclass: #ArgRejestr

instanceVariableNames: ' rej'

classVariableNames: ''

poolDictionaries:''

... Inicjalizacja

dajWartość

^Rejestry at: rej

wstawWartość: w

Rejestry at: rej put: w

Argument subclass: #ArgRejestrStała

instanceVariableNames: ' rej wartość'

classVariableNames: ''

poolDictionaries:''

... Inicjalizacja

dajWartość

^Pamięć at: ((Rejestry at: rej) + wartość)

wstawWartość: w

Pamięć at: ((Rejestry at: rej) + wartość) put: w

Argument subclass: #ArgAdres

instanceVariableNames: ' adr'

classVariableNames: ''

poolDictionaries:''

... Inicjalizacja

dajWartość

^Pamięć at: adr

wstawWartość: w

Pamięć at: adr put: w


Przyk ad debugger

Instrukcja

podklasa klasy Object

atrybuty: zależne od typu instrukcji

metody:

breakpointustawia pułapkę na instrukcji

breakpointCond: warustawia pułapkę warunkową

war - obiekt klasy Warunek o której wiemy tylko tyle,

że ma metodę oblicz zwracajacą true lub false

clearBreakpointusuwa pułapkę

runrozpoczyna wykonanie od tej instrukcji

unrunrozpoczyna cofanie od tej instrukcji

Możemy założyć, że zmienne Pamięć i Rejestry mają zawsze jakąś

wartość (czyli zawsze jest jakaś zawartość pamięci i rejestrów).

Atrybutem każdej instrukcji powinnna być pułapka - możemy na razie

przyjąć, że jest to obiekt klasy Breakpoint z metodą

czyStop

zwracającą true, jeśli należy się zatrzymać.

Ponadto każda instrukcja powinna wiedzieć, jaka jest następna po niej.

W przypadku skoków - co byłoby wykonane, gdyby nie było skoku.

Problem: cofanie programu

1. Kazda instrukcja musi wiedzieć, co było wykonane przed nią (jeśli nic,

tzn. jest to pierwsza wykonywana instrukcja, to nie można się cofnąć.

2. Są przecież pętle! Więc każda instrukcja musi mieć stos instrukcji,

które przed nią były wykonane.

3. Instrukcje zmieniające stan pamięci lub rejestrów muszą mieć

zapamiętaną zmienianą wartość.

4. Znowu ze względu na pętle to musi być stos wartości!


Przyk ad debugger

Hierachia klas:

Instrukcja(atr: nast - następna instrukcja do wykonania;

poprzednie - stos poprzednich instrukcji;

bp - pułapka, obiekt klasy Breakpoint lub nil)

Operacja(atr: l, r - obiekty klasy Argument

wartości - stos zmienianych wartości)

MOV

ADD

SUB

Skok(atr: instr - gdzie skoczyć, obiekt klasy Instrukcja)

SkokWar (atr: arg - obiekt klasy Argument)

IfZero

IfMinus

Zakładamy, że mamy klasę Stos ze zwyczajowymi metodami.

Object subclass: #Instrukcja

instanceVariableNames: ' nast poprzednie bp '

classVariableNames: ''

poolDictionaries:''

breakpoint

bp := Breakpoint new

breapointCond: war

bp := BreakpointCond new: war

clearBreakpoint

bp := nil

run

bp isNil ifFalse: [bp czyStop ifTrue: [^self]].

self wykonaj

run: instr

poprzednie push: instr.

self run

unrun

bp isNil ifFalse: [bp czyStop ifTrue: [^self]].

self cofnij.

poprzednie isEmpty ifFalse: [ poprzednie pop unrun]


Przyk ad debugger

Instrukcja subclass: #Operacja

instanceVariableNames: ' l r wartości '

......

wykonaj

wartości push: l dajWartość.

self oblicz.

nast isNil ifFalse: [nast wykonaj: self]

cofnij

l wstawWartość: (wartości pop)

Operacja subclass: #MOV

instanceVariableNames: ''

........

oblicz

l wstawWartość: (r dajWartość)

Instrukcja subclass: #Skok

instanceVariableNames: ' instr '

......

wykonaj

instr wykonaj: self.

Skok subclass: #IfZero

instanceVariableNames: 'war'

.....

wykonaj

(arg dajWartość = 0) ifTrue: [instr wykonaj: self]

ifFalse: [ nast isNil ifFalse: [nast wykonaj: self]]


  • Login