Wykład 6
Wsparcie makroasemblera dla budowy
blokowej
Bloki programu
Mechanizmy organizujące bloki
Działanie asemblera/loadera/linkera
Organizowanie bloków w procesorach z segmentacją
• Metoda organizowania pamięci odpowiadająca sposobowi
korzystania z pamięci przez programistę
• program jest zestawem bloków (segmentów). Blok jest
jednostką logiczną:
program
główny
procedura/y
funkcja/e
obiekt/y
zmienne lokalne
zmienne globalne
blo
k wspólny
stos
tablice
Segmenty programu
łatwiej zapewnić współdzielenie kodu i
ochronę danych
1
3
2
4
1
4
2
3
przestrzeń „użytkownika”
fizyczna przestrzeń pamięci
Segmenty/bloki programu
Segmenty/bloki programu
Współdzielenie segmentów/bloków programu
Bity dostępu przypisane
do segmentów – ochrona
i współdzielenie na
poziomie segmentów
Środki programowania
• definiowanie segmentów programu + nadawanie cech
związanych z tłumaczeniem segmentów
• przekształcanie segmentów:
-
grupowanie, scalanie, ustalanie kolejności
• kształtowanie pliku wynikowego
język asemblera
asembler i konsolidator
Środki programowania
• architektury
nie stosujące segmentacji pamięci
-
mechanizmy języka asemblera;
- ochrona
– realizowana programowo
• architektury
z segmentacją pamięci
-
odwzorowanie segmentów w programie w segmenty
pamięci „rozpoznawane” przez procesor
-
ochrona realizowana sprzętowo
Zależność od architektury procesora
blok 0
blok 1
blok 2
blok 0
blok 1
blok 2
program źródłowy
blok 0
blok 1
blok 2
bloki programu
Bloki/segmenty programu
Odnoszą się do fragmentów programu, które mogą być
docelowo uporządkowane inaczej w kodzie wynikowym
niż występują w programie źródłowym
• Pola danych umieszczone w pobliżu korzystających
z nich instrukcji
• stanowiące procedury fragmenty umieszczone w
tekście programu głównego
main
function
data
blok 0
blok 1
blok 2
program źródłowy
asemblacja
Bloki programu - asembler
• Asembler grupuje części kodu/danych, które są rozproszone w
programie źródłowym, a posiadają ten sam charakter
– Korzyści:
• Grupowanie zapewnia oszczędność miejsca i krótszy kod
• Dzięki tej funkcjonalności – związane ze sobą dane i kod
w
programie źródłowym
mogą być umieszczone blisko siebie, dla
lepszej czytelności i panowania nad programem
Bloki programu
Blok 1
Blok 2
Blok 1
Blok 3
Bloki programu
Dyrektywa USE:
USE [blockname]
ominięcie pola danych
Kolejność w pliku wynikowym:
1, 3, 2, 4
T
u zaczyna się blok domyślny
Bloki programu (przykład)
Użyj bloku CBLKS
4096 bajtów
Użyj bloku CDATA
Blok
domyślny
Blok „CDATA”
Blok „CBLKS”
Bloki programu (przykład cd)
Użyj domyślnego bloku
Użyj bloku CDATA
Blok
domyślny
Blok
„CDATA”
Użyj domyślnego bloku
Blok domyślny (bez nazwy) zawiera instrukcje wykonywalne
Blok CDATA zawiera pojedyncze dane (jedno-
kilka słów)
Blok CBLKS zawiera dane blokowe (tablice)
Użyj bloku CDATA
Bloki programu (przykład cd)
Blok
domyślny
Blok
„CDATA”
• asembler logicznie rearanżuje bloki grupując składowe
• rezultat – odpowiada wynikowi przepisania programu do
postaci, w której występują zwarte segmenty
Bloki programu – zadanie asemblera
..........
CDATA
CBLKS
asemblacja
•
Asembler używa wielu liczników programu
– dyrektywa
USE
•
Dyrektywy wyróżniają sekcje, które zostaną załadowane w różne
obszary pamięci
•
I przejście asemblera
– Każdy blok programu – odrębny LC
– Każda etykieta w bloku –
adres względny
w stosunku do
początku bloku
– Na zakończenie I przejścia, końcowa dla bloku wartość LC =
długość bloku
– Asembler może przypisać każdemu blokowi adresy
początkowe w pliku wynikowym
•
II przejście asemblera
– Adres każdego symbolu może być wyliczony poprzez
sumowanie adresu początkowego bloku z
adresem względnym
symbolu
Bloki programu – zadanie asemblera
nie stosowane, gdy segmenty pamięci
Grupowanie bloków przez asembler
adr wzgl nr bloku
Grupowanie bloków przez asembler
adr wzgl nr bloku
• asembler „wewnętrznie” rearanżuje kod i dane w zwarte
bloki
• kod generowany do pliku wynikowego nie musi być
fizycznie przeorganizowany
– wystarczy, że asembler
wpisze właściwy adres początkowy dla każdej sekcji
Przykład zawartości pliku wynikowego
Bloki programu – asembler/loader
Bloki programu – zadanie loadera
dane
zainicjalizowane
dane
zainicjalizowane
Dodatkowe korzyści:
nie ma potrzeby
generowania kodu dla
tych 2 bloków –
wystarczy zarezerwować
miejsce w pamięci
Bloki programu – korzyści z grupowania
4096 b
Bloki programu – korzyści z grupowania
Dodatkowe korzyści:
duże bloki danych poza
obszarem kodu programu
-
można zastosować
krótsze skoki
Bloki programu dla procesorów wspierających
segmenty pamięci
(ukryte)
Dostęp do danych z różnych segmentów
wymaga zmiany (częste?) zawartości
rejestru segmentowego
grupować
dane w segmentach
nazwa
SEGMENT
[[READONLY]] [[align]] [[combine]] [[use]] [[
‘class’]]
……………..
....................
nazwa
ENDS
Nazwa
: umożliwia grupowanie części segmentu
(każde kolejne użycie tej samej nazwy = kontynuacja
segmentu) i określenie adresu
Segmenty
nazwa
SEGMENT
[[READONLY]] [[
align
]] [[combine]] [[use]] [[
‘class’]]
BYTE, ALIGN(n), WORD, DWORD, PARA, PAGE
Segmenty
BYTE
2 4 16 256
WORD, DWORD, PARA, PAGE
nazwa
SEGMENT
[[READONLY]] [[align]] [[
combine
]] [[use]] [[
‘class’]]
PUBLIC, STACK, COMMON, ATaddress, PRIVATE
Segmenty
Określa porządek wpisywania segmentów z
tą samą nazwą
do
pliku wynikowego
PUBLIC, STACK
– przed wpisaniem
do pliku wynikowego
składowe segmentu są scalane; (STACK pozwala
zainicjalizować rejestr SS)
PRIVATE
–
w pliku wynikowym
składowe segmentu nie są
scalone
nazwa
SEGMENT
[[READONLY]] [[align]] [[combine]] [[use]] [[
‘class’
]]
‘CODE’, ‘STACK’, ‘DATA’,
‘CONST’
Segmenty
Określa kolejność postępowania
przez konsolidator
z
segmentami o różnych nazwach
(1) asembler łączy wszystkie segmenty PUBLIC o tej samej nazwie
(2) po złączeniu wpisuje do pliku wyjściowego w kolejności, jak w
programie źródłowym (z adresem początkowym pierwszego
składnika segmentu)
(3)
konsolidator
rearanżuje segmenty. Zaczyna od pierwszego
segmentu w pliku, następnie szuka segmentu o tej samej klasie i
konsoliduje go, wpisując jako kolejny do pliku .EXE
(4) powtarza kroki dla następnych klas
Segmenty - grupowanie
nazwa
SEGMENT
[[
READONLY
]] [[align]] [[combine]] [[
use
]] [[
‘class’]]
USE16, USE32, FLAT
Segmenty
Określa, czy generowany kod
ma odpowiadać 16, czy 32-
bitowym przesunięciom
-
wywołania procedur, powroty
-skoki
asembler wykaże błąd, gdy
napotka instrukcję
zapisującą do segmentu
nie zabezpiecza
przed
zapisaniem w trakcie
wykonania programu
READONLY
Typowe definiowanie segmentów
...............zmienne
...............instrukcje
obszar stosu
Segmenty
W procesorze rejestry segmentów np. : CS (+ FS), DS (+ GS), SS, ES.
Użytkownik odpowiedzialny za załadowanie właściwych wartości do
rejestrów segmentowych.
Przykład:
PROG
SEGMENT
ASSUME
CS:
PROG
START
:
ADD
AX, BX
ADD
AX, CX
INT 3
PROG
ENDS
END
START
Procesory z segmentacją pamięci
Segmenty
Dyrektywa ASSUME:
ASSUME segreg:segloc
Asembler wylicza przesunięcia, które wraz z zawartością rej. segment.
określają pełny adres zmiennej symbolicznej.
Przesunięcia do danych
z innego, niż bieżący, segmentu poprzedza „adresem” tego segmentu
Dyrektywa informuje asembler jaką wartość rej. segment. ustalił
użytkownik. Nie generuje kodu ML!
ASSUME zwykle nie potrzebna dla CS (CS automatycznie przypisany
do bieżącego segmentu programu
nazwa segmentu lub grupy
(równoważne wyrażenie)
Segmenty - ASSUME
Program omija wpis do rejestru
segmentowego; dostęp do danych
błędnie
wykonany zostanie w segmencie
DSEG1 (z przesunięciami jak do
segmentu DSEG2)!
Segmenty - ASSUME
Dobra praktyka:
umieść ASSUME przed procedurą
.... jeśli tu następna procedura poprzedź ją dyrektywą ASSUME
Używaj nazw w postaci:
DS1:variable
Grupowanie segmentów
Rozmieszczenie w pamięci
Instrukcja początkowa programu
Dyrektywa END:
END symbol
Etykieta instrukcji startowej
Przykład