Asm i C dla 8051 Nieznany (2)

background image

Wykład z budowy i programowania układów

mikroprocesorowych

Wykład prowadził profesor Jerzy Jakubiec.

Notowali Rafał Kała i Adam Szojda.

background image
background image

Spis rzeczy

1

Programowanie w j ˛ezyku asembler

1

1.1

Podstawowe wła´sciwo´sci asemblera . . . . . . . . . . . . . . . . . . . . . . .

1

1.1.1

Proces powstawania i tłumaczenia programu

. . . . . . . . . . . . . .

1

1.1.2

Składnia instrukcji asemblera

. . . . . . . . . . . . . . . . . . . . . .

2

1.1.3

Komentowanie programu . . . . . . . . . . . . . . . . . . . . . . . . .

3

1.1.4

Elementarne obiekty j˛ezyka . . . . . . . . . . . . . . . . . . . . . . .

3

1.1.5

Tworzenie nazw i operacje na słowniku . . . . . . . . . . . . . . . . .

5

1.1.6

Dyrektywy rezerwacji pami˛eci . . . . . . . . . . . . . . . . . . . . . .

6

1.1.7

Dyrektywa ko ´ncz ˛

aca program . . . . . . . . . . . . . . . . . . . . . .

7

1.2

Makroasembler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

7

1.2.1

Ogólne wła´sciwo´sci makroasemblera . . . . . . . . . . . . . . . . . .

7

1.2.2

Asemblacja warunkowa

. . . . . . . . . . . . . . . . . . . . . . . . .

7

1.2.3

Makrodefinicje . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

8

1.3

Tworzenie programów w postaci modułowej

. . . . . . . . . . . . . . . . . .

8

1.3.1

Moduły programowe . . . . . . . . . . . . . . . . . . . . . . . . . . .

8

1.3.2

Absolutne i wzgl˛edne tłumaczenie modułów programowych . . . . . .

10

1.3.3

Atrybuty nazw w programach modułowych . . . . . . . . . . . . . . .

11

1.3.4

Relokowalo´s´c modułów . . . . . . . . . . . . . . . . . . . . . . . . .

12

1.3.5

Współu˙zywanie nazw w modułach . . . . . . . . . . . . . . . . . . . .

13

1.3.6

Doł ˛

aczanie modułu zawieraj ˛

acego kod ´zródłowy programu . . . . . . .

14

1.4

Sekcje . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

14

1.4.1

Typy sekcji . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

14

1.4.2

Składnia dyrektywy .SECTION . . . . . . . . . . . . . . . . . . . . .

15

1.4.3

Sekcje rejestrowe i sekcje bitowe

. . . . . . . . . . . . . . . . . . . .

15

1.5

Lokowanie sekcji w pami˛eci . . . . . . . . . . . . . . . . . . . . . . . . . . .

16

1.5.1

Sposoby lokowania sekcji . . . . . . . . . . . . . . . . . . . . . . . .

16

1.5.2

Zwi ˛

azki mi˛edzy sekcjami

. . . . . . . . . . . . . . . . . . . . . . . .

16

1.5.3

Sterowanie lokowaniem sekcji . . . . . . . . . . . . . . . . . . . . . .

17

1.5.4

Konsolidacja programu o strukturze sekcyjnej . . . . . . . . . . . . . .

18

2

Programowanie w C

µ

K rodziny Intel 8051

21

2.1

Proces uzyskiwania programu wynikowego dla programów w C . . . . . . . .

21

2.2

Program rozruchowy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

22

2.2.1

Rodzaje programu rozruchowego

. . . . . . . . . . . . . . . . . . . .

22

2.2.2

Definiowanie rodzaju mikrokontrolera . . . . . . . . . . . . . . . . . .

23

i

background image

Spis rzeczy

2.2.3

Deklaracja rejestrów roboczych . . . . . . . . . . . . . . . . . . . . .

26

2.2.4

Przesuwanie danych . . . . . . . . . . . . . . . . . . . . . . . . . . .

27

2.2.5

Przygotowanie stosu . . . . . . . . . . . . . . . . . . . . . . . . . . .

28

2.2.6

Wywołanie programu w C . . . . . . . . . . . . . . . . . . . . . . . .

28

2.3

Organizacja danych w C . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

29

2.3.1

Typy danych i ich modyfikatory . . . . . . . . . . . . . . . . . . . . .

29

2.3.2

Organizacja ramki stosu . . . . . . . . . . . . . . . . . . . . . . . . .

30

2.3.3

Przekazywanie argumentów do funkcji

. . . . . . . . . . . . . . . . .

31

2.3.4

Rozmieszczenie zmiennych lokalnych w ramce stosu . . . . . . . . . .

33

2.3.5

Przechowywanie warto´sci zwracanych przez funkcj˛e . . . . . . . . . .

36

2.4

Przekazywanie danych mi˛edzy funkcjami a instrukcjami asemblera . . . . . . .

37

2.4.1

Wprowadzanie instrukcji asemblera do programu w C . . . . . . . . .

37

2.4.2

Dost˛ep do zmiennych lokalnych . . . . . . . . . . . . . . . . . . . . .

38

2.4.3

Dost˛ep do argumentów funkcji j˛ezyka C . . . . . . . . . . . . . . . . .

38

2.4.4

Adresowanie bezpo´srednie i po´srednie w programach w C . . . . . . .

39

Indeks

43

ii

background image

Spis rysunków

1.1

Proces tworzenia programu . . . . . . . . . . . . . . . . . . . . . . . . . . . .

1

1.2

Proces tworzenia programów w postaci modułowej . . . . . . . . . . . . . . .

10

1.3

Zwi ˛

azki mi˛edzy sekcjami . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

17

2.1

Proces uzyskiwania programu wynikowego dla programów w C . . . . . . . .

21

2.2

Struktura wewn˛etrznej pami˛eci RAM po zainicjowaniu stosu . . . . . . . . . .

29

2.3

Ramka stosu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

31

2.4

Kolejno´s´c argumentów funkcji w ramce stosu . . . . . . . . . . . . . . . . . .

32

2.5

Ramka stosu dla przykładu ze strony 33 . . . . . . . . . . . . . . . . . . . . .

34

2.6

Mapa pami˛eci zmiennych lokalnych . . . . . . . . . . . . . . . . . . . . . . .

34

2.7

Mapa ramki stosu funkcji z przykłady ze strony 33

. . . . . . . . . . . . . . .

36

iii

background image

Spis rysunków

iv

background image

1 Programowanie w j ˛ezyku asembler

1.1

Podstawowe wła ´sciwo ´sci asemblera

1.1.1

Proces powstawania i tłumaczenia programu

Program z´ródłowy

Program wynikowy

Tłumaczenie

Rysunek 1.1: Proces tworzenia programu

Proces tworzenia programu u˙zytkowego, niezale˙znie od zastosowanego j˛ezyka programo-

wania, przebiega w sposób przedstawiony ogólnie na rysunku 1.1. Proces ten mo˙zna okre ´sli´c
jako zespół działa ´n słu˙z ˛

acych przetworzeniu programu, tworzonego w sposób dogodny dla pro-

gramisty i specyficzny dla rodzaju oprogramowywanego zadania, na posta ´c dostosowan ˛

a do

potrzeb procesora realizuj ˛

acego program. Ta pierwotna posta ´c programu, nazywana programem

´zródłowym, ma zawsze posta´c symboliczn ˛

a i powstaje przy u˙zyciu edytora tekstu

1

. Program

wynikowy ma posta´c binarn ˛

a wyra˙zon ˛

a j˛ezykiem wewn˛etrznym (maszynowym) procesora. Pro-

ces tłumaczenia polega na nadawaniu warto´sci liczbowych nazwom symbolicznym. Elementem
składowym tego procesu jest równie˙z organizacja i zapis pami˛eci danych. Program ´zródłowy
stanowi ci ˛

ag instrukcji uszeregowanych w sposób wła´sciwy dla celów realizacji okre´slonego za-

dania. Posta´c instrukcji narzuca sposób tłumaczenia programu, okre´slaj ˛

ac zarazem podstawowy

podział j˛ezyków programowania. Wyró˙znia si˛e dwa podstawowe rodzaje j˛ezyków:

j˛ezyki maszynowo (sprz˛etowo) zorientowane nazywane asemblerami a w rozwini˛etej wer-
sji makroasemblerami,

j˛ezyki proceduralnie zorientowane, czyli tzw. j˛ezyki wy˙zszego rz˛edu.

Budowa asemblera dostosowana jest do wła´sciwo´sci sprz˛etowych procesora i urz ˛

adze ´n z nim

współpracuj ˛

acych. Wyst˛epuje wi˛ec ´scisły zwi ˛

azek mi˛edzy budow ˛

a mikrokomputera a postaci ˛

a

instrukcji j˛ezyka typu asembler. Zewn˛etrznie ten zwi ˛

azek przejawia si˛e w taki sposób, ˙ze jedna

instrukcja w j˛ezyku asemblerowym koduje jeden rozkaz maszynowy (jest to tzw. własno´s´c jeden
na jeden
). Symbolika j˛ezyka sprowadza si˛e do u˙zywania:

1

Czyli MS Word odpada, na szcz˛e´scie . . . ;-)

1

background image

1

Programowanie w j˛ezyku asembler

symbolicznych (mnemonicznych) kodów rozkazów,

symbolicznych adresów i danych.

Reasumuj ˛

ac mo˙zna powiedzie´c, ˙ze j˛ezyk typu asembler jest j˛ezykiem symbolicznym sprz˛etowo

zorientowanym.

Podstawow ˛

a cech ˛

a j˛ezyka wy˙zszego poziomu jest orientacja proceduralna, tzn. ˙ze j˛ezyki te

s ˛

a budowane pod k ˛

atem optymalizacji okre´slonego rodzaju zada ´n. Dzieli si˛e je na:

j˛ezyki algorytmiczne,

j˛ezyki symulacyjne,

j˛ezyki do tworzenia baz danych, itp. itd.

Programy pisane w tych j˛ezykach maj ˛

a praktycznie tak ˛

a sam ˛

a posta ´c dla ró˙znych typów kom-

puterów. Ró˙zni ˛

a si˛e natomiast programy tłumacz ˛

ace, które musz ˛

a by ´c inne dla ka˙zdego typu

komputera (procesora). Istotn ˛

a zewn˛etrzn ˛

a cech ˛

a j˛ezyków wy˙zszego rz˛edu jest zast˛epowanie

ka˙zdej ich instrukcji wieloma rozkazami maszynowymi.

1.1.2

Składnia instrukcji asemblera

Instrukcja jest elementarnym poleceniem dla programu tłumacz ˛

acego. Inaczej mo˙zna po-

wiedzie´c, ˙ze instrukcja jest podstawowym elementem j˛ezyka. Instrukcja mo˙ze:

kodowa´c rozkaz,

zawiera´c dyrektyw˛e,

by´c pusta (komentarz).

Dyrektywa jest to taki rodzaj instrukcji, która słu˙zy do organizowania programu. Na ogół

dyrektywy nie generuj ˛

a kodu, za wyj ˛

atkiem takich, które wprowadzaj ˛

a liczby do pami˛eci da-

nych.

Instrukcja jest zapisana w oddzielnej linii programu ´zródłowego, zatem linia programu jest

jednostk ˛

a organizacji programu ´zródłowego. W linii programu wyró˙znia si˛e cztery pola (zawar-

to´s´c ka˙zdego z nich mo˙ze by´c pusta):

pole_etykiety: pole_operacji pole_argumentów ;pole komentarza

Dwukropek jest wyró˙znikiem pola etykiety, przed komentarzem zawsze musi wyst˛epowa ´c ´sred-
nik. W polu etykiety umieszczana jest nazwa wprowadzana przez programist˛e. U˙zycie nazwy
w polu etykiety nadaje jej warto´s´c w procesie tłumaczenia programu według okre´slonych reguł.
Nazwa w polu etykiety musi by´c zako ´nczona dwukropkiem. Długo´s´c nazwy w polu etykiety
zale˙zy od dopuszczalnej długo´sci nazw danej wersji asemblera. W przypadku pakietu 2500AD
wynosi ona 32 znaki, przy czym zalecane jest u˙zywanie nie wi˛ecej ni˙z 10 znaków. Zawarto ´s´c

2

background image

1.1

Podstawowe wła´sciwo´sci asemblera

pola operacji okre´sla rozkaz maszynowy lub dyrektyw˛e. Natomiast pole argumentówpodaje
dodatkowe argumenty, których liczba i rodzaj zale˙z ˛

a od zawarto´sci pola operacji. Pole komen-

tarza, poprzedzone ´srednikiem, mo˙ze zawiera´c dowolny ci ˛

ag znaków. Komentarz w procesie

tłumaczenia jest przez asembler pomijany. Przykład:

int0:

ACALL przeslij ;prze´

slij komunikat na P1

RETI

komunikat_1: .db ’komunikat 1’,0Dh,0Ah,0

1.1.3

Komentowanie programu

Standardowo komentarz realizuje si˛e przy u˙zyciu ´srednika. Przykład:

;To jest komentarz

;************************

;* Data: xx-xx-xxxx

*

;* Nazwisko programisty *

;* Wersja programu

*

;************************

U˙zycie dyrektywy

.COMMENT

pozwala na swobodne operowanie komentarzem. Cały tekst mi˛e-

dzy znakami przyj˛etymi przez programist˛e jako ograniczniki stanowi komentarz. Przykład:

.comment #

To jest przykład u˙

zycia dyrektywy .comment

Cały tekst zawarty mi˛

edzy hash-ami jest komentarzem

Taki komentarz mo˙

ze mie´

c wiele linii, ale te 3 chyba wystarcz ˛

a...

#

1.1.4

Elementarne obiekty j ˛ezyka

Elementarnymi obiektami j˛ezyka typu asembler, czyli wielko´sciami, na których j˛ezyk wy-

konuje działania, s ˛

a:

stałe,

nazwy,

wyra˙zenia arytmetyczne.

Stałe mog ˛

a by´c zapisane jako:

1. dziesi˛etne: D

2. dwójkowe: B

3. ósemkowe: O, Q

3

background image

1

Programowanie w j˛ezyku asembler

4. szesnastkowe: H

5. znakowe

Stałe liczbowe opatrzone s ˛

a odpowiednim symbolem literowym. Pomini˛ecie symbolu oznacza

liczb˛e dziesi˛etn ˛

a. U˙zycie dyrektywy

.RADIX

powoduje zmian˛e standardowej podstawy liczb

u˙zywanych w programie. Argumentem tej dyrektywy jest jeden z wymienionych symboli lub
liczba b˛ed ˛

aca podstaw ˛

a danego kodu

2

. Stałe znakowe ograniczone s ˛

a znakami pojedynczego

lub podwójnego cudzysłowu. Przykład:

127

;stała dziesi˛

etna

101101101b

;stała binarna

0A3h

;stała szestnastkowa. Je˙

zeli pierwsza cyfra stałej

;jest liter ˛

a to nale˙

zy j ˛

a poprzedzi´

c zerem

’napis’

;pi˛

ecio bajtowa stała znakowa

.radix 16

;ustaw standard liczb szesnastkowy

Nazwa jest ci ˛

agiem liter i cyfr zaczynaj ˛

acym si˛e od litery. Liczba znaków w nazwie zale˙zy

od standardu asemblera. W ró˙znych asemblerach zmienia si˛e tak˙ze zbiór dozwolonych znaków
alfanumerycznych, z których mog ˛

a by´c budowane nazwy i inne obiekty j˛ezyka.

Ostatni ˛

a konstrukcj ˛

a składniow ˛

a jest wyra˙zenie arytmetyczne b˛ed ˛

ace ci ˛

agiem nazw i stałych

przedzielonych dwuargumentowymi operatorami arytmetycznymi. Ka˙zda nazwa lub stała mo˙ze
by´c poprzedzona operatorem jednoargumentowym. Dopuszcza si˛e stosowanie nawiasów w celu
ł ˛

aczenia argumentów. Operatory wyra˙ze ´n arytmetycznych:

1. Operatory jednoargumentowe

.NOT.

’, ‘

\

’,

‘!

’ – zaprzeczenie logiczne,

+

’ – opcjonalne oznacza argument dodatni,

-

’ – negacja arytmetyczna (uzupełnienie dwójkowe),

<

’, ‘

.HIGH.

’ – starszy bajt szesnastobitowego słowa,

>

’, ‘

.LOW.

’ – młodszy bajt szesnastobitowego słowa.

2. Operatory dwuargumentowe

**

’ – pot˛egowanie całkowite,

*

’ – mno˙zenie całkowite,

/

’ – dzielenie całkowite,

.SHR.

’ – przesuw w prawo,

.SHL.

’ – przesuw w lewo,

+

’ – suma arytmetyczna,

2

2, 8, 10 lub 16

4

background image

1.1

Podstawowe wła´sciwo´sci asemblera

-

’ – ró˙znica arytmetyczna,

.AND.

’, ‘

&

’ – iloczyn logiczny,

.OR.

’, ‘

^

’ – suma logiczna,

.XOR.

’ – suma modulo 2 (ró˙znica symetryczna)

Warto´sci wyra˙ze ´n arytmetycznych zapisywane s ˛

a w słowie o´smio lub szesnastobitowym w za-

le˙zno´sci od kontekstu wyra˙zenia. Nale˙zy podkre´sli´c, ˙ze w asemblerze wyra˙zenia arytmetyczne
słu˙z ˛

a do obliczania warto´sci nazw, a nie do realizacji oblicze ´n przez program wynikowy. War-

to´sci wyra˙ze ´n arytmetycznych s ˛

a obliczane podczas procesu tłumaczenia, a nie w trakcie jego

realizacji.

W trakcie asemblacji mo˙zliwe jest stosowanie porówna ´n, których wynikiem jest

1

gdy wa-

runek jest spełniony lub

0

gdy nie jest. Operatory porówna ´n:

=

’, ‘

.EQ.

’ – równo´s´c,

>

’, ‘

.GT.

’ – wi˛eksze ni˙z,

<

’, ‘

.LT.

’ – mniejsze ni˙z,

.UGT.

’ – wi˛eksze ni˙z dla liczb bez znaku (ang. unsigned),

.ULT.

’ – mniejsze ni˙z dla liczb bez znaku.

1.1.5

Tworzenie nazw i operacje na słowniku

Asembler w chwili rozpocz˛ecia tłumaczenia zawiera pewien wst˛epnie zdefiniowany słownik

Umieszczone s ˛

a w nim nazwy rozkazów procesora, nazwy dyrektyw, nazwy innych obiektów

j˛ezyka (np. nazwy rejestrów). Nazwy te mog ˛

a by ´c u˙zywane w programie wg. okre´slonych reguł,

zgodnie ze sposobem budowy rozkazów mikroprocesora i konstrukcji asemblera. Podstawowym
sposobem dopisania nowej nazwy do słownika jest umieszczenie jej w polu etykiety. W procesie
tłumaczenia nazwa b˛ed ˛

aca etykiet ˛

a uzyskuje warto´s´c równ ˛

a bie˙z ˛

acemu wska´znikowi umiesz-

czenia

3

. Bie˙z ˛

acy wska´znik umieszczenia jest zmienn ˛

a procesu tłumaczenia przybieraj ˛

ac ˛

a war-

to´sci równe adresom, pod którymi lokowany jest kod wynikowy. Programista powinien ustawi ´c
warto´s´c wska´znika przed napisaniem pierwszej linii programu zawieraj ˛

acej rozkaz. Do tego celu

słu˙zy dyrektywa

.ORG

4

, której argumentem jest warto´s´c adresu nadawana, przy ka˙zdym u˙zyciu

dyrektywy, bie˙z ˛

acemu wska´znikowi umieszczenia. W pakiecie 2500AD pomini˛ecie pocz ˛

atko-

wej dyrektywy

.ORG

powoduje przyj˛ecie domy´slnej warto´sci wska´znika umieszczenia

$=0000

.

Przykład:

;program przykładowy

.org 0

;$=0000h

ajmp start

.org 3

;obsługa przerwania INT0

3

Oznaczanym ‘

$

4

ORIGIN

5

background image

1

Programowanie w j˛ezyku asembler

int0:

acall 100h ;prze´

slij komunikat na port P1

reti

.org 30h

start:

acall 40h

;inicjacja mikrokontrolera

czekaj: nop

ajmp czekaj

;czekaj na przerwanie

Innym sposobem dopisania nazwy do słownika, czyli nadania jej warto ´sci, jest u˙zycie jednej
z dyrektyw

.SET

lub

.EQU

, których argumentem jest wyra˙zenie arytmetyczne. Ró˙znica pomi˛e-

dzy

.SET

a

.EQU

sprowadza si˛e do tego, ˙ze nazwa zdefiniowana przez

.SET

mo˙ze by ´c w tym

samym programie okre´slana wielokrotnie w ró˙znych miejscach – nazwa redefiniowalna. Nato-
miast zdefiniowanie nazwy dyrektyw ˛

a

.EQU

wyklucza jej powtórne okre´slenie. Nazwa taka jest

nieredefiniowajna i nazywana jest cz˛esto absolutn ˛

a.

Program tłumacz ˛

acy musi jednoznacznie przypisa ´c ka˙zdej nowej nazwie odpowiedni ˛

a war-

to´s´c. Proces tłumaczenia przebiega sekwencyjnie linia po linii od pocz ˛

atku programu. Ist-

nieje mo˙zliwo´s´c wielokrotnego definiowania tych samych nazw, a ponadto mo˙ze si˛e zdarzy ´c, ˙ze
w procesie tłumaczenia danej linii nazwa w niej u˙zyta nie została jeszcze zdefiniowana. Z po-
wy˙zszych powodów ka˙zdej tworzonej przez programist˛e nazwie musz ˛

a by ´c przyporz ˛

adkowane

atrybuty maj ˛

ace posta´c jednobitowej informacji towarzysz ˛

acej nazwie. Podstawowe atrybuty to:

1. warto´s´c (

0

– brak warto´sci,

1

– jest warto´s´c) ,

2. logiczne – redefiniowalno´s´c

Atrybut okre´slono´sci mówi o tym, czy w chwili tłumaczenia danej linii nazwa ma ju˙z warto ´s´c.
Warunkiem koniecznym poprawno´sci programu jest to, aby po przetłumaczeniu ostatniej linii
programu wszystkiem nazwy w słowniku były okre´slone.

1.1.6

Dyrektywy rezerwacji pami ˛eci

Słu˙z ˛

a do rezerwowania pami˛eci operacyjnej na pola robocze programu (s ˛

a to elementy pa-

mi˛eci danych) oraz do ustalania pocz ˛

atkowych warto´sci tych pól.

Dyrektywa

.DB

.DB lista_argumentów

Po przetworzeniu tej dyrektywy w kolejnych bajtach kodu wynikowego s ˛

a umieszczane warto ´sci

odpowiednich wyra˙ze ´n arytmetycznych lub warto´sci kodów ASCII znaków tworz ˛

acych stałe

znakowe.

Dyrektywa

.DW

Dyrektywa ta ma analogiczn ˛

a składni˛e jak

.DB

, z tym ˙ze jej argumenty słu˙z ˛

a do okre ´slania

warto´sci szesnastobitowych.

6

background image

1.2

Makroasembler

Dyrektywa

.DS

Słu˙zy do rezerwacji liczby komórek okre´slonej przez parametr b˛ed ˛

acy jej argumentem.

W rezerwowany obszar nie jest wpisywana ˙zadna informacja lub jest on zerowany (na ogół
na ˙z ˛

adanie programisty).

1.1.7

Dyrektywa ko ´

ncz ˛

aca program

Dyrektyw ˛

a ko ´ncz ˛

ac ˛

a program jest dyrektywa

.END

.

1.2

Makroasembler

1.2.1

Ogólne wła ´sciwo ´sci makroasemblera

Makroasembler jest asemblerem rozsze˙zonym o dodatkowe dyrektywy i konstrukcje, któ-

rych u˙zycie pozwala programi´scie na wykonanie pewnych operacji na tek´scie programu ´zródło-
wego. W wyniku tych operacji mo˙zna:

kre´sli´c warunek uwzgl˛ednienia lub zignorowania fragmentu programu ´zródłowego,

zdefiniowa´c pewn ˛

a instrukcj˛e, której u˙zycie jest równoznaczne wstawieniu ci ˛

agu linii pro-

gramu,

spowodowa´c wstawienie w program ´zródłowy ci ˛

agu linii skojarzonych z wcze´sniej okre-

´slon ˛

a instrukcj ˛

a.

W przypadku makroasemblera proces tłumaczenia ró˙zni si˛e w pewnym stopniu od tłumaczenia
w prostym asemblerze. Ka˙zda wczytana linia podlega wst˛epnej analizie i ew. przetworzeniu.
W wyniku tego linia mo˙ze:

zosta´c zignorowana,

by´c przekazana do dalszej asemblacji bez zmian,

doprowadzi´c do wytworzenia ci˛egu linii z jednej linii wczytanej.

Operacje te zawsze poprzedzaj ˛

a wła´sciwe tłumaczenie w sensie prostego asemblera.

1.2.2

Asemblacja warunkowa

Podstawowa konstrukcja programowa słu˙z ˛

aca do warunkowego tłumaczenia programu ma

nast˛epuj ˛

ac ˛

a posta´c:

.if [warunek]

.

;program tłumaczony je´

sli warunek spełniony (1)

.

7

background image

1

Programowanie w j˛ezyku asembler

.else

.

;program tłumaczony je´

sli warunek nie jest spełniony (0)

.

.endif

Dyrektywa

.ELSE

nie jest obligatoryjna. Jej brak oznacza, ˙ze dany fragment programu jest tłu-

maczony, lub nie, bez ˙zadnej alternatywy. Argument dyrektywy

.IF

okre ´sla warto´s´c logiczn ˛

a

w ten sposób, ˙ze warto´s´c wyra˙zenia arytmetycznego u˙zytego jako argument ró˙znej od zera od-
powiada prawda, warto´sci równej zero odpowiada fałsz.

1.2.3

Makrodefinicje

Makrodefinicje definuje si˛e przez umieszczenie fragmentu programu ´zródłowego mi˛edzy

dyrektywami

.MACRO

i

.ENDM

w nast˛epuj ˛

acy sposób:

nazwa: .macro lista,parametrów,formalnych

.

.

;tre´

c makrodefinicji

.

.

.endm

Przykład:

wstaw:

.macro rozkaz, warto´

c

rozkaz

etykieta: .db warto´

c

.endm

Tre´s´c makrodefinicji mo˙ze stanowi´c dowolny ci ˛

ag znaków, który nie musi miec składni popraw-

nej instrukcji i mo˙ze si˛e składa´c z praktycznie dowolnej liczby linii. Ogólnie definicja makroin-
strukcji słu˙zy do tego, aby za pomoc ˛

a jednej linii programu wstawi ´c ci ˛

ag linii okre´slony w tej

definicji. Lini˛e zawieraj ˛

ac ˛

a nazw˛e makrodefinicji nazywa si˛e wywołaniem makroinstrukcji. Za-

wiera ona w polu parametrów ci ˛

ag wyra˙ze ´n arytmetycznych w liczbie odpowiadaj ˛

acej liczbie

parametrów formalnych. Argumenty te nazywa si˛e parametrami aktualnymi. Makroasembler
przetwarzaj ˛

ac wywołanie makroinstrukcji (rozwijaj ˛

ac makroinstrukcj˛e) zast˛epuje odpowiednie

parametry formalne ich aktualnymi warto´sciami. Wywołanie mo˙ze by´c powtarzane dowoln ˛

a

ilo´s´c razy.

1.3

Tworzenie programów w postaci modułowej

1.3.1

Moduły programowe

Ko´ncowa posta´c programu wynikowego powstaje z reguły jako wynik scalania wielu jego

ró˙znych fragmentów. Przyczyny tego maj ˛

a ró˙zny charakter. Wynikaj ˛

a one przede wszystkim

8

background image

1.3

Tworzenie programów w postaci modułowej

z konieczno´sci tworzenia programu przez zespół programistów, a zatem podziału na fragmenty
tworzone równolegle. Bardzo cz˛esto korzysta si˛e przy tym z bibliotek programów standar-
dowych (np. mno˙zenia i dzielenia zmiennoprzecinkowego, konwersji liczb. . . ) tworzonych
i przechowywanych w postaci odr˛ebnych modułów. Równie˙z wła´sciwo´sci fizyczne oprogra-
mowywanego procesora zmuszaj ˛

a do wyodr˛ebnienia fragmentów programu. Na przykład dla

mikrokontrolerów z rozdzielon ˛

a pami˛eci ˛

a programu i danych kod wynikowy trzeba rozdzieli ´c

zgodnie z przeznaczeniem do odpowiednich rodzajów pami˛eci. Podział logiczny dokonywany
jest przez programist˛e w celu wyodr˛ebnienia samodzielnych fragmentów nazywanych proce-
durami. Z reguły procedura jest podprogramem komunikuj ˛

acym si˛e z innymi procedurami za

pomoc ˛

a okre´slonych standardów przekazywania danych. Zatem procedury mog ˛

a by ´c budowane

niezale˙znie – zmiany wprowadzone w ich obr˛ebie nie maj ˛

a bezpo´sredniego wpływu na inne

procedury. Taki sposób tworzenia programu nazywany jest modularnym i stanowi jeden z pod-
stawowych standardów dobrego programowania.

Podstawow ˛

a jednostk ˛

a programow ˛

a z punktu widzenia asemblera jest moduł

5

. Jest to taki

ci ˛

ag linii programu, który dla asemblera stanowi jedn ˛

a cało´s´c. Oznacza to, ˙ze dla ka˙zdego

modułu asembler rozpoczyna swoje działanie od pocz ˛

atku (mówi si˛e, ˙ze ma miejsce restart

asemblera). Przede wszystkim modułem jest plik z programem ´zródłowym. Mo˙zna jednak
wyodr˛ebni´c moduły w ramach pojedynczego pliku. Słu˙z ˛

a do tego dyrektywy asemblera

.MOD

i

.ENDMOD

.

Z tego, ˙ze poszczególne moduły tłumaczone s ˛

a niezale˙zne, a nast˛epnie zestawiane w jedn ˛

a

cało´s´c, wynikaj ˛

a dwa istotne fakty:

kod programu uzyskany w wyniku asemblacji musi mie ´c tak ˛

a postac aby mógł by´c umiesz-

czony w dowolnym obszarze pami˛eci – posta ´c taka nazywa si˛e postaci ˛

a relokowaln ˛

a

(przesuwaln ˛

a),

z konieczno´sci tworzenia programów z po´srednich postaci przesuwalnej wynika potrzeba
dwustopniowej realizacji procesu tłumaczenia (rys. 1.2). W pierwszej fazie przy u˙zyciu
asemblera tworzone s ˛

a programy w postaci relokowalnej, w drugiej fazie moduły relo-

kowalne s ˛

a zespalane w procesie konsolidacji

6

w jedn ˛

a cało´s´c lokowan ˛

a w obszarach

pami˛eci o ´sci´sle okre´slonych adresach. T ˛

a drug ˛

a faz˛e realizuje program nazywany konso-

lidatorem lub programem ł ˛

acz ˛

acym

7

.

Techniczne aspekty procesu konsolidacji wymagaj ˛

a podziału modułów na mniejsze cz˛e ´sci, ele-

mentarne z punktu widzenia konsolidatora. Wynika to przedewszystkim z konieczno ´sci podziału
ka˙zdego modułu na cz˛e´sci zawieraj ˛

ace program i dane, a tak˙ze na inne fragmenty zwi ˛

azane ze

specyfik ˛

a konstrukcji procesera. Dla INTEL 8051 wyodr˛ebnianie fragmentów programu zwi ˛

a-

zane jest z podziałem pami˛eci RAM na wewn˛etrzn ˛

a i zewn˛etrzn ˛

a, wydzieleniem rejestrów ro-

boczych i specjalnych oraz pami˛eci adresowanej bitowo.

Definiuje si˛e poj˛ecie sekcji

8

lub segmentu jako takiego, spójnego logicznie, fragmentu pro-

gramu, który jest traktowany przez konsolidator jako jedna elementarna cało ´s´c. Oznacza to, ˙ze

5

ang. module

6

ł ˛

aczenia, linkowania

7

ang. linker

8

ang. section

9

background image

1

Programowanie w j˛ezyku asembler

Asembler

Moduł 1

Moduł n

Asembler

Konsolidator

Program

wynikowy

*.obj

*.asm

*.asm

*.obj

*.exe

Rysunek 1.2: Proces tworzenia programów w postaci modułowej

mo˙zna wskaza´c konsolidatorowi adres, pod którym nale˙zy umie´sci´c dan ˛

a sekcj˛e oraz dodatkowe

parametry okre´slaj ˛

ace typ sekcji (np. sekcja z programem, danymi, sekcja rejestrowa. . . ).

Bior ˛

ac pod uwag˛e, ˙ze w procesie konsolidacji zespalane mo˙ze by ´c wiele modułów w ka˙z-

dym z nich mo˙zna na ogół wyró˙zni´c sekcje tego samego typu. Sekcje takie powinny by ´c ł ˛

aczone

ze sob ˛

a i umieszczane w zwartym obszrze pami˛eci. Zatem cz˛esto wygodzniej jest operowa ´c na

wi˛ekszych cało´sciach nazywanych grupami sekcji lub grupami. Grupa jest to zespół sekcji o ta-
kich samych nazwach w ró˙znych modułach traktowanych przez konsolidator tak jak pojedyncza
sekcja.

1.3.2

Absolutne i wzgl ˛edne tłumaczenie modułów programowych

Budowanie programu w postaci modułowej wymaga uzyskiwania po asemblacji kodu w po-

staci przesuwalnej umo˙zliwiaj ˛

acej ulokowanie modułu w dowolnym obszarze pami˛eci. Powo-

duje to z kolei konieczno´s´c przyporz ˛

adkowania ka˙zdemu modułowi adresu bazowego, który

stanowi adres odniesienia, wzgl˛edem którego okre´slane s ˛

a warto´sci wszystkich przesuwalnych

(relokowalnych) nazw w danym module. Ilustruje to poni˙zszy przykład

9

:

;program wyprowadzania komunikatu przez port P1

;adres pocz ˛

atku komunikatu w DPTR

.org

BAZA

pisz_kom1:

mov

dptr,#komunikat_1 ;ładuj rejestr bazowy

mov

r0,#0

;licznik znaków

dalej:

mov

a,r0

movc

a,@a+dptr

;pobierz znak

cjne

a,#0,nie_koniec ;czy koniec ła´

ncuch znaków?

ret

;tak

nie_koniec:

mov

p1,a

;nie

inc

r0

ajmp

dalej

;komunikat nr 1

kom_end:

.equ 0

;znak ko´

nca

komunikat_1: .db ’komunikat 1’,0ah,0dh,kom_end

9

U˙zyta w nim nazwa

BAZA

symbolizuje jedynie adres bazowy i słu˙zy do uwidocznienia relacji mi˛edzy tym adresem

a warto´sci ˛

a nazw relokowalnych.

10

background image

1.3

Tworzenie programów w postaci modułowej

Program ´zródłowy

Program wynikowy

aders (hex)

kod (hex)

.org BAZA

BAZA

pisz_kom1:

mov

dptr,#komunikat

_

1

BAZA

90 00 10

mov

r0,#0

BAZA+0003

78 00

dalej:

mov

a,r0

BAZA+0005

e8

movc a,@a+dptr

BAZA+0006

93

cjne a,#0,nie_koniec

BAZA+0007

b4 00 01

ret

BAZA+000a

22

nie_koniec:

mov

p1,a

BAZA+000b

f5 90

inc

r0

BAZA+000d

08

ajmp dalej

BAZA+000e

01 05

kom_end:

.equ 0

BAZA+0010

komunikat_1:

.db ’komunikat 1’,0ah,0dh,kom_end

BAZA+0010

6b 6f 6d

75 6e 69

itd. . .

Analizuj ˛

ac uzyskany program wynikowy mo˙zna stwierdzi ´c, ˙ze adres ka˙zdej komórki pami˛eci

daje si˛e wyrazi´c w postaci sumy dwóch składników: adresu bazowego (który tutaj symbolizuje
ogólnie nazwa

BAZA

) oraz cz˛e´sci stałej. Adres bazowy jest jednakowy dla wszystkich komórek

przechowuj ˛

acych kod wynikowy danego modułu programowego, przy czym ulega on zmianie

wraz ze zmian ˛

a poło˙zenia modułu w pami˛eci. Cz˛e´s´c stała adresu komórki nie zmienia si˛e nie-

zale˙znie od lokalizacji modułu bowiem wskazuje ona odległo´s´c od pocz ˛

atku modułu. Z powy˙z-

szego wynika, ˙ze operacje zwi ˛

azane z działaniem na adresach komórek przy zmianie poło˙zenia

modułu w pami˛eci s ˛

a proste – polegaj ˛

a na dodaniu do ka˙zdej warto ´sci stałej, zwi ˛

azanej nie-

rozł ˛

acznie z ka˙zdym kodem rozkazu uzyskanym po asemblacji, adresu bazowego okre ´slaj ˛

acego

aktualne poło˙zenie modułu w pami˛eci. Programista ma do dyspozycji szereg mo˙zliwo ´sci od-
działywania na adres bazowy modułu – zarówno przy u˙zyciu asemblera jak i w trakcie procesu
konsolidacji.

1.3.3

Atrybuty nazw w programach modułowych

W ka˙zdym programie wyst˛epuj ˛

a etykiety, czyli nazwy symblolizuj ˛

ace adresy okre ´slonych

miejsc w pami˛eci. W trakcie zmiany poło˙zenia modułu w pami˛eci musz ˛

a one podlega ´c takim

samym regułom przemieszczania jak inne adresy. Ponadto mo˙zna równie˙z definiowa ´c nazwy,
które zachowuj ˛

a stał ˛

a warto´s´c niezale˙znie od poło˙zenia modułu. Dla powy˙zszego przykładu

mo˙zna zestawi´c nast˛epuj ˛

ac ˛

a tablic˛e nazw:

Nazwa

Warto´s´c

Atrybyt absolutno´sci

pisz_kom1

BAZA+0000

0

dalej

BAZA+0005

0

nie_koniec

BAZA+000b

0

komunikat_1

BAZA+0010

0

kom_end

00

1

11

background image

1

Programowanie w j˛ezyku asembler

Nazwy, których warto´s´c zale˙zy od poło˙zenia modułu w pami˛eci nazywane s ˛

a przesuwalnymi

(relokowalnymi), natomiast nazwy o stałych warto´sciach – absolutnymi. Ka˙zdej nazwie mo˙zna
przypisa´c atrybut absolutno´sci, który stanowi dla programu tłumacz ˛

acego wska´znik czy nale˙zy,

lub nie, modyfikowa´c nazw˛e przy zmianie poło˙zenia modułu.

1.3.4

Relokowalo ´s ´c modułów

Mo˙zna nakaza´c tłumaczenie fragmentów programu w sposób absolutny umieszczaj ˛

ac je

mi˛edzy dyrektywami:

.ABSOLUTE

,

.RELATIVE

.

Dyrektywa

.ABSOLUTE

powoduje przej´scie asemblera w tryb tłumaczenia absolutnego, co ozna-

cza, ˙ze wszystkie nazwy w tym trybie maj ˛

a atrybut absolutno´sci równy 1. Dyrektywa

.RELATIVE

przywraca tryb wzgl˛edny działania asemblera. Tryb ten jest zazwyczaj trybem domy ´slnym
asemblera o ile programista nie naka˙ze inaczej.

Tryb absolutny powinien by´c stosowany tylko w szczególnych przypadkach, poniewa˙z po-

ł ˛

aczenie modułów absolutnych z relokowalnymi mo˙ze prowadzi ´c do utworzenia niepoprawnych

sekwencji programowych. Poniewa˙z cz˛esto przyjmuje si˛e zasad˛e, ˙ze nie wyró˙znia si˛e w spe-
cjalny sposób modułów absolutnych, w zwi ˛

azku z czym s ˛

a one ł ˛

aczone z innymi modułami na

takich samych zasadach. Oznacza to, ˙ze w module absolutnym mog ˛

a ulega ´c przesuni˛eciu adresy

komórek pami˛eci natomiast nazwy definiowane w tym module pozostaj ˛

a stałe. Przykład:

adres

kod

.absolute

.org 20

petla:

nop

0020

00

ajmp petla

0021

01 20

Nazwa

PETLA

w tym przykładzie uzyskuje warto´s´c absolutn ˛

a

0020h

. Załó˙zmy, ˙ze ł ˛

aczy si˛e po-

wy˙zszy program z innymi, w efekcie czego program ten zostaje umieszczony od adresu

1000h

:

adres

kod

petla:

nop

1020

00

ajmp petla

1021

01 20

Zatem posta´c ko ´ncowa (wynikowa) tego fragmentu programu jest niepoprawna. Wynika st ˛

ad

wniosek, ˙ze za wyj ˛

atkiem szczególnych przypadków moduły programowe nale˙zy tłumaczy ´c

w sposób wzgl˛edny, a ich wła´sciw ˛

a lokalizacj˛e w pami˛eci okre´sla´c dopiero w trakcie konsolida-

cji.

Przykład ten ilustruje równie˙z specyfik˛e stosowania dyrektywy

.ORG

w modułach przesu-

walnych – wskazuje ona odległo´s´c miejsca w module programowym od pocz ˛

atku modułu wska-

zywanego przez adres bazowy. Standardowo przyjmuje si˛e w procesie asemblacji, ˙ze adres
bazowy ka˙zdego z modułów równa si˛e zera. W trakcie konsolidacji do tego adresu dodawany

12

background image

1.3

Tworzenie programów w postaci modułowej

jest adres przesuni˛ecia modułu (ang. offset), który jest dodawany do wszystkich adresów wska-
zywanych przez dyrektyw˛e

.ORG

. Powoduje to, ˙ze argument tej dyrektywy i przesuni˛ecie dodaj ˛

a

si˛e.

1.3.5

Współu˙zywanie nazw w modułach

Budowanie programu w postaci modułowej, a nast˛epnie ł ˛

aczenie modułów w jeden wspólny

program wymaga definiowania nazw wspólnych dla wielu modułów. Równie˙z w przypadku
doł ˛

aczania modułów bibliotecznych niezb˛edne jest u˙zycie nazw definiowanych przez moduły.

To wszystko powoduje, ˙ze w trakcie asemblacji w pewnych modułach pojawiaj ˛

a si˛e nazwy,

których warto´sci nie s ˛

a okre´slone w danym module.

Nazwa, która jest definowana w danym module i jest udost˛epniana równie˙z na zewn ˛

atrz

modułu, co oznacza ˙ze jest wa˙zna w całym programie, nazywana jest nazw ˛

a globaln ˛

a. Wskazy-

wanie nazw globalnych odbywa si˛e przy u˙zyciu dyrektywy:

.GLOBAL ci ˛

ag,nazw

Dyrektywa ta nadaje nazw ˛

a atrybut globalno´sci.

Nazwy, które s ˛

a u˙zywane w danym module, przy zało˙zeniu, ˙ze s ˛

a definiowane w innym, na-

zywane s ˛

a zewn˛etrznymi z punktu widzenia tego modułu. Nazwy takie wskazuje si˛e dyrektyw ˛

a:

.EXTERNAL ci ˛

ag,nazw

U˙zycie tej dyrektywy powoduje nadanie wskazanym nazw ˛

a atrybutu zewn˛etrzno´sci.

Z powy˙zszych uwag wynika, ˙ze modułowe tworzenie programów wymaga wyposa˙zenia

nazw w trzy dodatkowe atrybuty: absolutno´sci, globalno´sci i zewn˛etrzno´sci. Atrybuty te s ˛

a

niezb˛edne w procesie konsolidacji do uzyskania kodu programu wynikowego i stwierdzenia
poprawno´sci wszystkich działa ´n składaj ˛

acych si˛e na ten proces.

Przykład ilustruj ˛

acy sposób posługiwania si˛e nazwami współu˙zywanymi w ró˙znych mody-

łach:

.module ;moduł 1

.global start

.external init

start: acall init

.endmod

.module ;moduł 2

.global init

init:

mov a,#10h

.

.

.

ret

.endmod

13

background image

1

Programowanie w j˛ezyku asembler

1.3.6

Doł ˛

aczanie modułu zawieraj ˛

acego kod ´zródłowy programu

Podstawowy moduł programowy ma posta´c pliku. Wyró˙znikiem pliku jest jego nazwa

(w przykadku modułów asemblerowych wymagane jest rozszerzenie

*.asm

). Ka˙zdy moduł jest

tłumaczony oddzielnie, w wyniku czego uzyskiwany jest plik z kodem przesuwalnym (

*.obj

)

nosz ˛

acy na ogół tak ˛

a sam ˛

a nazw˛e jak plik ´zródłowy. Pliki z kodem przesuwalnym poddawane s ˛

a

konsolidacji polegaj ˛

acej na zespoleniu odpowiednich fragmentów programu (sekcji) z ró˙znych

modułów i lokowanie ich w wybranych obszarach pami˛eci.

Istnieje sposób bardzo prosty cho´c znacznie mniej elestyczny od wy˙zej wymienionego słu-

˙z ˛

acy do ł ˛

aczenia modułów. Jest ono wówczas wykonywane na poziomie tekstu programu ´zró-

dłowego za pomoc ˛

a dyrektywy:

.INCLUDE nazwa_pliku.asm

1.4

Sekcje

1.4.1

Typy sekcji

Sekcja – wyró˙zniony fragment programu stanowi ˛

acy elementarn ˛

a cało ´s´c z punktu widze-

nia konsolidatora. Nadaje on sekcji jedno stałe przesuni˛ecie (ang. offset). Cz˛esto takie same
konstrukcje programowe jak sekcje nazywane s ˛

a w innych asemblerach segmantami, przy czym

na ogół sposób definiowania segmentów nie pozwala na tak du˙z ˛

a eleastyczno ´s´c struktury pro-

gramu jak to ma miejsce w przypadku sekcji. Opisany sposób definiowania sekcji zwi ˛

azany jest

ze specyficznymi cechami budowy mikrokontrolerów rodziny INTEL 8051. Mo˙zna wskaza ´c
dwa sposoby definiowania sekcji: przy u˙zyciu standardowych dyrektyw tybów sekcji oraz jako
sekcji u˙zytkowanika.

U˙zycie standardowych typów sekcji powoduje, ˙ze w trakcie konsolidacji s ˛

a one traktowane

priorytetowo w stosunku do sekcji definiowanych przez u˙zytkownika. Oznacza to, ˙ze s ˛

a one lo-

kowane jako pierwsze, przy czym priorytet lokowania samych sekcji standardowych jest zgodny
z zestawieniem.

.CODE

– sekcja z programem,

.DATA

– sekcja z danymi,

.RSECT

– sekcja rejestrowa,

.BSECT

– sekcja w pami˛eci bitowej.

Typ

.CODE

ma najwy˙zszy priorytet, a ponadto jest standardowym (domy´slnym) typem sekcji

– ka˙zdemu fragmentowi programu ´zródłowego o nieokre´slonym typie sekcji nadawany jest ten
typ.

14

background image

1.4

Sekcje

1.4.2

Składnia dyrektywy .SECTION

U˙zytkownik definiuje sekcje za pomoc ˛

a dyrektywy:

nazwa_sekcji: .SECTION argumenty_opcjonalne

Argumenty dyrektywy wskazuj ˛

a sposób lokowania sekcji w pami˛eci. Nazwa zdefiniowana przy

u˙zyciu dyrektywy

.SECTION

sama mo˙ze by´c u˙zywana jak dyrektywa, a konkretnie jako prze-

ł ˛

acznik sekcji. Przykład:

nop

;sekcja CODE

.DATA

;przeł ˛

acz na sekcj˛

e DATA

.ds 1

;bajt w sekcji DATA

SEKCJA_1 .SECTION

;definiuje i aktywizuje sekcj˛

e u˙

zytkownika

nop

;rozkaz w sekcji SEKCJA_1

.CODE

nop

;a ten w sekcji CODE

.SEKCJA_1 ;przeł ˛

acza na sekcje u˙

zytkownika

nop

;sekcja u˙

zytkownika mo˙

ze zawiera´

c rozkazy

.ds 1

;i dane

Powy˙zszy przykład pokazuje, ˙ze poszczególne fragmenty programu mo˙zna zestawia ´c w sekcje
w sposób praktycznie dowolny. Bior ˛

ac pod uwag˛e, ˙ze sekcje tego samego typu (w przypadku

sekcji u˙zytkownika oznacza to sekcje o tej samej nazwie) z ró˙znych modułów s ˛

a zespalane

w jedn ˛

a cało´s´c przez konsolidator daje to programi´scie elastyczne narz˛edzie tworzenia struk-

tur programowych dostasowanych zarówno do specyfiki budowy pami˛eci mikrokontrolera jak
i konstrukcji programu.

1.4.3

Sekcje rejestrowe i sekcje bitowe

Sekcje rejestrowe – konstrukcje obejmuj ˛

ace pojedyncze rejestry lub ich grupy. Definiowane

s ˛

a za pomoc ˛

a dyrektywy

.RSECT

lub przy u˙zyciu modyfikatora

REG

po dyrektywie

.SECTION

.

Jedyn ˛

a dyrektyw ˛

a, która mo˙ze wyst˛epowa ´c wewn ˛

atrz sekcji rejestrowej jest dyrektywa

.DS

.

Sposób tworzenia sekcji ilustruje przykład:

.RSECT

;przeł ˛

acza na sekcj˛

e rejestrow ˛

a

reg1:

.ds 1

sekcja_rej: .section reg ;definiuje rejestrow ˛

a sekcj˛

e u˙

zytkownika

reg2:

.ds 1

reg3:

.ds 1

Sekcje bitowe – umo˙zliwiaj ˛

a indywidualne adresowanie bitów. Mo˙zna utworzy ´c j ˛

a za po-

moc ˛

a standardowej dyrektywy

.BSECT

lub za pomoc ˛

a modyfikatora

BIT

. Wewn ˛

atrz sekcji bito-

wej mo˙zna u˙zywa´c jedynie dyrektywy

.DS

.

15

background image

1

Programowanie w j˛ezyku asembler

1.5

Lokowanie sekcji w pami ˛eci

1.5.1

Sposoby lokowania sekcji

Umieszczenie sekcji w okre´slonym miejscu pami˛eci polega na podaniu adresu sekcji, tj.

adresu pierwszej komórki pami˛eci zadeklarowanej jako pocz˛etek sekcji oraz ew. adresu ko ´nca
sekcji (chocia˙zby w celu unikni˛ecia braku pamieci – przepełnienia). Adres sekcji mo˙ze by ´c
wskazany w programie ´zródłowym jako argument dyrektywy

.SECTION

lub w trakcie konsoli-

dacji. Zalecany jest drugi sposób bo zapewnia znacznie wi˛eksz ˛

a elastyczno ´s´c procesu lokowa-

nia.

Mo˙zna wyró˙zni´c kilka rodzajów sekcji ze wzgl˛edu na ich sposób lokowania w pami˛eci.

Bior ˛

ac pod uwag˛e sposób wykorzystania celowe jest wyodr˛ebnienie trzech rodzajów sekcji:

sekcje bezpo´srednio lokowane w pami˛eci (ang. direct),

sekcje po´srednio lokowane w pami˛eci (ang. indirect),

sekcje referencyjne (ang. reference only).

Sekcja bezpo´srednia charakteryzuje si˛e tym, ˙ze jest u˙zywana w tym obszarze pami˛eci, w którym
została ulokowana w trakcie konsolidacji. Oznacza to, ˙ze kod wynikowy i wszystkie nazwy
zdefiniowane dla danej sekcji nie podlegaj ˛

a ˙zadnym zmianom w trakcie realizacji programu

u˙zytkowego.

Po´srednie lokowanie sekcji polega na tym, ˙ze sekcja po konsolidacji jest umieszczona w jed-

nym miejscu, a nast˛epnie po rozpocz˛eciu pracy programu zostaje przeniesiona w inne niejsce
gdzie jest u˙zytkowana. Oznacza to, ˙ze warto´sci wszystkich nazw definiowanych w danej sek-
cji s ˛

a wyznaczane nie dla miejsca umieszczenia jej po konsolidacji lecz zgodnie z lokalizacj ˛

a

sekcji w trakcie jej u˙zytkowania przez program (np. dla sekcji z danymi przemieszczenie jej
z pami˛eci programu ROM do pami˛eci danych RAM mo˙ze mie ´c na celu umo˙zliwienie jej aktu-
alizacji w trakcie realizacji programu).

Sekcja refernecyjna jest sekcj ˛

a pust ˛

a tzn. w trakcie konsolidacji nie jest w niej lokowany

˙zaden kod wynikowy. Jest kreowana jedynie dla celów wyznaczania warto ´sci adresów niezb˛ed-

nych dla programu u˙zytkowego. (np. mo˙ze to by ´c tablica w pami˛eci danych, której adresy
s ˛

a wyznaczane w trakcie kosolidacji i przekazywane pod postaci ˛

a odpowiednich nazw do pro-

gramu u˙zytkowego w celu umo˙zliwienia działania na elementach tej tablicy.)

1.5.2

Zwi ˛

azki mi ˛edzy sekcjami

Sekcje po przeprowadzeniu konsolidacji mog ˛

a by ´c:

odseparowane tzn. lokowane w oddzielnych obszarach pami˛eci np. jako sekcje z danymi
i programem,

sklejone (ang. stacked),

nało˙zone na siebie (ang. common).

16

background image

1.5

Lokowanie sekcji w pami˛eci





















































Pamie˛c´

Sekcja 1

Sekcja 2

















































Pamie˛c´

Adres kon´ca sekcji 2

Adres pocz. sekcji 1

Sekcja 1

Sekcja 2

Adres kon´ca sekcji1 =
Adres pocz. sekcji 2

         

         

         

         

         

         

         

         

         

         

         

         

         

         

         

         

         

         

         

         

         

         

         

         

Pamie˛c´

Sekcja 1

Sekcja 2

Adres kon´ca sekcji 1

Adres kon´ca sekcji 2

Adres pocz. sekcji 1 =
Adres pocz. sekcji 2

odseparowane

sklejone

nało˙zone na siebie

Rysunek 1.3: Zwi ˛

azki mi˛edzy sekcjami

1.5.3

Sterowanie lokowaniem sekcji

Rozmieszczenie sekcji w pami˛eci mo˙ze by ´c sterowane z poziomu asemblera za pomoc ˛

a

argumentów dyretywy

.SECTION

:

OFFSET

Argument

OFFSET adres

powoduje bezpo´srednie umieszczenie sekcji pod wskaza-

nym adresem przy zało˙zeniu, ˙ze adres pocz ˛

atku sekcji wynosi zero. U˙zycie dyrek-

tywy:

sekcja1:

.section offset 100h

powoduje utworzenie sekcji o nazwie “

sekcja1

” i nakazuje ulokowanie jej w pa-

mi˛eci programu z przesuni˛eciem

100h

w stosunku do pocz ˛

atku sekcji okre ´slonego

dyrektyw ˛

a

.ORG

.

INDIRECT

Po´srednie lokowanie sekcji umo˙zliwia argument

INDIRECT addres

, gdzie

adres

wskazuje miejsce, do którego sekcja zostanie przeniesiona po rozpocz˛eciu pracy
programu. U˙zycie dyrektywy:

sekcja1:

.section offset 100h, indirect 200h

spowoduje fizyczne umieszcznie sekcji w pami˛eci programu ROM pocz ˛

awszy od

adresu

100h

, przy czym etykiety definiowane w tej sekcji uzyskuj ˛

a warto ´sci, jak

gdyby sekcja była lokowana od adresu

200h

. Po inicjacji program u˙zytkowy w pierw-

szej fazie działania przemieszcza sekcje z pami˛eci ROM do pami˛eci RAM pod adres

200h

i dysponuj ˛

ac warto´sciami adresów wła´sciwymi dla tego obszaru mo˙ze od tego

momentu u˙zywa´c przemieszczonej sekcji.

STACKED

Argument

STACKED

powoduje lokoawnie sekcji tu˙z nad sekcj ˛

a poprzedni ˛

a. Nazywa

si˛e to sklejaniem sekcji. Sekcja poprzednia musi by ´c zdefiniowana jako bezpo´sred-
nia. Np. zdefiniowanie sekcji w sposób jak ni˙zej:

sekcja1:

.section offset 100h

;sekcja bezpo´

srednia

a nast˛epnie:

sekcja2:

.section stacked

powoduje, ˙ze

sekcja2

jest lokowana tu˙z nad

sekcja1

.

17

background image

1

Programowanie w j˛ezyku asembler

AUTO_STACK

W praktyce cz˛esto jest stosowana technika polegaj ˛

aca na sklejaniu sekcji z frag-

mentów umieszczonych w ró˙znych plikach (modułach). Sklejanie takich fragmen-
tów umo˙zliwia argument

AUTO_STACK

. Nazwy sklejanych fragmentów definiowa-

nych równie˙z jako sekcje musz ˛

a by´c we wszystkich plikach jednakowe.

REF_ONLY

Wskazanie sekcji referencyjnej nast˛epuje za pomoc ˛

a argumentu

REF_ONLY

. U˙zycie

dyrektywy:

sekcja1:

.

section offset 100h, ref_only

spowoduje jedynie takie wyznaczenie adresów i nazw zwi ˛

azanych z

sekcja1

ja-

kie s ˛

a wła´sciwe w przypadku umieszczenia jej z przesuni˛eciem

100h

. Jednak bez

fizycznego umieszczania sekcji w tym obszarze.

RANGE

Ka˙zdej sekcji mo˙zna przypisa´c obszar umieszczenia za pomoc ˛

a parametrów:

RANGE adres1 adres2

COMMON

Sekcje o tej samej nazwie w ró˙znych plikach mog ˛

a by´c nakładane na siebie przy

u˙zyciu arguemntu

COMMON

. Jednak w trakcie deklaracji sekcji tego rodzaju w pierw-

szym pliku nie mo˙zna u˙zy´c argumentu

COMMON

. Sekcja w pozostałych plikach mu-

sz ˛

a by´c natomiast deklarowane z tym argumentem oraz musz ˛

a by´c typu referencyj-

nego, gdy˙z inaczej w pliku wynikowym pojawiłoby si˛e wiele rekordów z kodem
odnosz ˛

acym si˛e do tego obszaru adresowego.

1.5.4

Konsolidacja programu o strukturze sekcyjnej

Wskazywanie miejsca, gdzie wstawi´c sekcj˛e realizowane z poziomu asemblera ma ograni-

czone zastosowanie. Nie wszystkie działania mog ˛

a by ´c wykonane (np. te z doł ˛

aczaniem modu-

łów bibliotecznych), a ponadto ich elastyczno´s´c jest znacznie mniejsza od działa ´n realizowanych
przez konsolidator. A tak˙ze ka˙zda zmiana sposobu i miejsca lokowania sekcji zmusza do zmiany
programu ´zródłowego, który tym samym musi by ´c znów tłumaczony. Wła´snie dlatego zalecane
jest
, aby wszystkich manipulacji na sekcjach dokonywa ´c z poziomu konsolidatora (w trakcie
konsolidacji). Cz˛esto konsolidatory wyposa˙zone s ˛

a w ´srodki przeznaczone do tego celu.

Konsolidator pakietu 2500AD dysponuje specjalnym j˛ezykiem przeznaczonym do przekazy-

wania polece ´n konsolidacji w postaci pliku wsadowego. Nazwy polece ´n stanowi ˛

a słowa angiel-

skie dobrane tak, ˙ze ich zestawienia stanowi ˛

a pełny komentarz do działa ´n zleconych konsoli-

datorowi. Zatem analiza pliku wsadowego steruj ˛

acego procesem konsolidacji w takim trybie,

nazywanym rozszerzonym (ang. enhanced) pozwala na uzyskanie pełnego obrazu konsolidacji.
Zmiany tego procesu wymagaj ˛

a tylko poprawek w pliku wsadowym, co realizuje si˛e za pomoc ˛

a

prostego edytora tekstu.

Przykład 1:

Załó˙zmy, ˙ze konsolidowany jest pojedynczy plik ´zródłowy stanowi ˛

acy jedn ˛

a sek-

cj˛e. Zawiera dyrektyw˛e

ORIGIN

wskazuj ˛

ac ˛

a adres pocz ˛

atku programu. Plik wsadowy steruj ˛

acy

konsolidacj ˛

a program w trybie rozszerzonym ma posta ´c:

version v0.1.1

option: executable

18

background image

1.5

Lokowanie sekcji w pami˛eci

input: nazwa_pliku_wej´

sciowego

output: nazwa_pliku_wyj´

sciowego

locate: CODE at 0h

Poszczególne linie w tym przykładzie zawieraj ˛

a polecenia konsolidacji, przy czym

‘:

’ stanowi

separator oddzielaj ˛

acy nazw˛e polecenia od jego argumentu. Znaczenie poszczególnych linii:

1. Słowo kluczowe

version

wskazuje, ˙ze dany plik zawiera polecenia w trybie rozszerzo-

nym. Jest to niezb˛edne, bo stosowany jest tak˙ze standardowy tryb wsadowy, w którym
polecenia maj ˛

a inn ˛

a posta´c.

2. Słowo

option

wskazuje rodzaj pliku wyj´sciowego:

executable

– plik z kodem binarnym,

intel hex

– plik z kodem w standardzie HEX Intela,

high level

– nakazuje utworzenie dodatkowego pliku wyj´sciowego z danymi nie-

zb˛ednymi w trakcie uruchamiania programu przy u˙zyciu symulatora,

load map

.

3. Argumentem polecenia

input

jest nazwa pliku wej´sciowego poddawanego konsolidacji.

4. Polecenie

output

zawiera nazw˛e pliku wyj´sciowego, którego rodzaj okre´slaj ˛

a argumenty

polecenia

option

5. Polecenie

locate

wskazuje adres umieszczenia poszczególnych sekcji. Interpretowane

jest jako dodatkowe przesuni˛ecie w stosunku do adresu pocz ˛

atku programu okre ´slonego

dyrektyw ˛

a

ORIGIN.

Przykład 2:

Dla zało˙ze ´n jak w poprzednim przykładzie nale˙zy zbudowa ´c plik wsadowy taki,

aby mo˙zna było przył ˛

aczy´c moduły biblioteczne, a plik wyj´sciowy był w standardzie

intel

hex

, a zarazem aby został utworzony plik uruchomieniowy za pomoc ˛

a symulatora. Plik konso-

lidacji ma wówczas posta´c:

version

option: loca map, intel hex

input: nazwa_pliku_wej´

sciowego

output: nazwa_pliku_wyj´

sciowego

library: nazwa_pliku bibliotecznego

locate: CODE at 0h

19

background image

1

Programowanie w j˛ezyku asembler

20

background image

2 Programowanie w C

µ

K rodziny Intel 8051

2.1

Proces uzyskiwania programu wynikowego dla programów w C

Pliki doła˛czene przez

uz˙ytkownika

w C

Plik z´ródłowy

Standardowe pliki nagłówkowe doła˛czane

na poziomie je˛zyka C (*.h)

Pliki doła˛czene przez

uz˙ytkownika

uz˙ytkownika

biblioteczne

Programy

Standardowe

programy

biblioteczne

Kompilator

asemblerowy

Plik z´ródłowy

programu rozruch.

Asembler

s´rodowisko (*.def)

Pliki definiuja˛ce

Pliki

relokowalne

rozruchowy

Konsolidator

Plik

Program

Bibliotekarz

Raport z kompilacji

(*.lst)

Pliki z kodem wynikowym

(*.hex, *.exe, *.sym, *.def)

programu (*.map)

Plik z mapa˛ pamie˛ci

Rysunek 2.1: Proces uzyskiwania programu wynikowego dla programów w C

Doprowadzenie programu napisanego w C do realizacji przez mikrokontroler (lub jego sy-

mulator) jest procesem wieloetapowym. Mo˙zna wyró˙zni ´c w nim conajmniej pi˛e´c niezb˛ednych
kroków:

napisanie w j˛ezyku asembler programu rozruchowego,

przetłumaczenie programu rozruchowego,

21

background image

2

Programowanie w C µK rodziny Intel 8051

kompilacja programu w C do postaci asemblerowej, a nast˛epnie przetłumaczenie go do
postaci relokowalnej,

wskazanie standardowych plików bibliotecznych doł ˛

aczanych w trakcie konsolidacji,

konsolidacja programu rozruchowego, programu w C oraz programów bibliotecznych
w wymienionej kolejno´sci.

Programy w j˛ezyku C wymagaj ˛

a przygotowania ´srodowiska, w którym s ˛

a realizowane. Polega

to ogólnie na zarezerwowaniu miejsca w pami˛eci dla okre´slonego rodzaju danych, zainicjowa-
nia układów wej´scia-wyj´scia do komunikacji z otoczeniem, przygotowania stosu a nast˛epnie na
oddaniu sterowania do programu w C, który standardowo rozpoczyna si˛e od funkcji

main()

.

Powy˙zsze działania realizuje program rozruchowy (ang. runtime start up program), który jest
napisany w j˛ezyku asembler. Jest on zwykle dostarczany przez producenta kompilatora, mo˙ze
by´c równie˙z zbudowany przez u˙zytkownika. Jest on dostosowywany do ró˙znych typów mi-
krokontrolerów rodziny 8051 za pomoc ˛

a plików definiuj ˛

acych struktur˛e rejestrów. Maj ˛

a one

rozszerzenie

*.def

i doł ˛

aczane s ˛

a za pomoc ˛

a dyrektywy

include

. U˙zytkownik mo˙ze modyfi-

kowa´c te pliki, mo˙ze równie˙z tworzy´c własne pliki definicyjne.

Programy w C równie˙z wymagaj ˛

a doł ˛

aczenia plików definicyjnych, które maj ˛

a jednak nieco

inny charakter. S ˛

a to tzw. pliki nagłówkowe

1

słu˙z ˛

ace do tworzenia prototypów funkcji biblio-

tecznych. Ich brak uniemo˙zliwia działanie tych funkcji. U˙zytkownik mo˙ze doł ˛

acza ´c równie˙z

własne pliki nagłówkowe.

Tłumaczenie programu w C odbywa si˛e dwuetapowo. Najpierw program w C tłumaczony

jest na program w asemblerze, a nast˛epnie program asemblerowy tłumaczony jest do postaci
relokowalnej. U˙zywaj ˛

ac odpowiedniego przeł ˛

acznika kompilatora powy˙zsze etapy mo˙zna zre-

alizowa´c jako jedn ˛

a cało´s´c.

Postacie relokowalne programu w C i programu rozruchowego s ˛

a poddane nast˛epnie kon-

solidacji ł ˛

acznie z programami bibliotecznymi. Tego rodzaju programy s ˛

a dostarczane przez

producenta. Mo˙zna równie˙z tworzy´c własne programy biblioteczne. U˙zytkownik mo˙ze doł ˛

a-

cza´c własne programy relokowalne do standardowej biblioteki za pomoc ˛

a programu o nazwie

librarian

2

. Wynikiem konsolidacji jest plik wykonywalny

*.exe

lub cz˛e´sciej jego posta´c he-

xadecymalna

*.hex

. Mo˙zna równie˙z uzyska´c pliki

*.sym

i

*.def

niezb˛edne gdy u˙zywa si˛e

symulatora. Ponadto programista mo˙ze za˙zyczy ´c sobie utworzenia raportu z kompilacji

*.lst

oraz pliku z map ˛

a programu

*.map

zawieraj ˛

acego dane na temat obszarów pami˛eci zajmowa-

nych przez sekcje oraz warto´sci nazw globalnych.

2.2

Program rozruchowy

2.2.1

Rodzaje programu rozruchowego

Program ten napisany jest w asemblerze i spełnia nast˛epuj ˛

ace zadania:

przygotowanie stosu i wywołanie pocz ˛

atkowej funkcji C (

main()

),

1

ang. header files

2

bibliotekarz

22

background image

2.2

Program rozruchowy

zapewnienie komunikacji mi˛edzy fizycznym urz ˛

adzeniem wej´scia-wyj´scia (lub systemem

operacyjnym) a programem w C,

zarezerwowanie obszarów na dane,

przeniesienie danych z pami˛eci programu do pami˛eci danych.

Pakiet 2500AD dostarcza trzy rodzaje programów rozruchowych:

przeznaczonych do zastosowanie w sytuacji gdy do przechowywania danych u˙zywa si˛e
wył ˛

acznie wewn˛etrznej pami˛eci RAM. Jest to tzw. tryb wewn˛etrzny kompilatora (ang.

internal memory mode). Program rozruchowy nosi nazw˛e

c8051ir.src

. W przypadku

gdy u˙zywa si˛e symulatora nale˙zy zastosowa ´c wersj˛e

c851sir.src

.

przeznaczonych do u˙zytku wył ˛

acznie z zewn˛etrzn ˛

a pami˛eci ˛

a RAM jako miejsca przecho-

wywania danych programu w C, co nazywane jest trybem zewn˛etrznym (ang. external
memory mode
). Stosowane s ˛

a wtedy odpowiednio programy rozruchowe:

c8051er.src

i

c8051ser.src

.

przeznaczonych do ł ˛

acznego wykorzystania obu rodzajów pami˛eci RAM. Jest to tzw. tryb

mieszany (ang. mixed memory mode):

c8051mr.src

i

c8051smr.src

.

Podj˛ecie decyzji co do rodzaju pami˛eci RAM, a wi˛ec i trybu kompilacji programu, wi ˛

a˙ze si˛e nie

tylko z wyborem rodzaju programu rozruchowego, ale równie˙z mi˛edzy innymi z wykorzysta-
niem odpowiednich programów bibliotecznych, sposobem definiowania zmiennych globalnych
itd. . . .

2.2.2

Definiowanie rodzaju mikrokontrolera

Rodzina 8051 obejmuje kilkadziesi ˛

at typów mikrokontrolerów. Program jest natomiast pi-

sany dla konkretnego typu, co oznacza, ˙ze u˙zywa on nazw rejestrów specjalnych odpowiednich
dla danego typu. Nazwy te s ˛

a u˙zywane zarówno na poziomie asemblera jak i j˛ezyka C. Nazwy

rejestrów specjalnych u˙zywane na tych poziomach s ˛

a ró˙zne. Oznacza to konieczno ´s´c realizacji

nast˛epuj ˛

acych działa ´n:

Na pocz ˛

atku programu rozruchowego nale˙zy u˙zy ´c dyrektywy

.CHIP

z argumentem okre-

´slaj ˛

acym typ mikrokontrolera (np.

.chip 8052

). Powoduje to doł ˛

aczenie do słownika

nazw asemblera całej grupy nazw rejestrów specjalnych i nazw bitów specyficznych dla
wskazanego typu mikrokontrolera. Od tego momentu nazwom tym zostaj ˛

a przypisane

warto´sci odpowiadaj ˛

ace adresom rejestrów i bitów, które nie mog ˛

a by ´c redefiniowane.

Umo˙zliwia to wskazanie tych nazw przez programist˛e bez konieczno ´sci odwoływanie si˛e
do adresów zwi ˛

azanych z tymi nazwami.

Na pocz ˛

atku sekcji

program

programu rozruchowego nale˙zy doł ˛

aczy ´c plik

c????sr.def

zawieraj ˛

acy globalne definicje nazw rejestrów specjalnych.

23

background image

2

Programowanie w C µK rodziny Intel 8051

Tak zdefiniowane nazwy poprzedzone doln ˛

a kresk ˛

a

3

(

_

) mog ˛

a by´c u˙zywane we wszystkich mo-

dułach pod warunkiem zdefiniowania ich jako zewn˛etrzne dla tych modułów. Dla programu
w C realizowane jest to za pomoc ˛

a makropolecenia doł ˛

aczaj ˛

acego plik nagłówkowy:

#include "c8052sr.h"

Zawarto ´s ´c plików definicyjnych

Plik

c8052sr.def

ma posta´c:

***********************************************************

* 8052 C compiler special functions registers definitions *

***********************************************************

spec_func_regs: .section reg,offset 0,ref_only

.globals on

_P0;

.reg 80h

_PCON:

.reg 77h

.

.

.

_SFB:

.reg 80h

.globals off

.ends

Plik nagłówkowy programu w C o nazwie

c8052sr.h

ma posta ´c:

/************************************************************/

/* 8052 C compiler special functions registers declarations */

/************************************************************/

.asm

.chip 8052

.endasm

extern near char P0; /* port 0 */

.

.

.

extern near char PCON; /* power control */

.

.

.

extern near char IE; /* interrupt enable control */

/*******************************************************/

/* 8052 C compiler special functions bits declarations */

/*******************************************************/

near struct special_finction bits

{

/* Bit name

Bit value */

3

normalnie nazywn ˛

a podkre´sleniem

24

background image

2.2

Program rozruchowy

/* P0 (Port 0) */

unsigned int P0_0:1 ; /* port 0, bit 0

80h*/

.

.

.

unsigned int P0_0:1;

/* port 0, bit 7

87h*/

/* TCON (Timer Control) */

unsigned int IT0:1; /*input INT0/transition activated 88h */

.

.

.

}

Doł ˛

aczenie tego pliku nagłówkowego umo˙zliwia w programach w C u˙zywanie nazw zdefinio-

wanych rejestrów i bitów jako zmiennych. Ilustruj ˛

a to przykłady:

#include “c8052sr.h”

near char c1;

main()

{

char c2;

c1=P0;

c2=P1;

P2=c2;

.local c2

.asm

mov .low. _c1,p0

mov _c2,p1

.endasm

}

Powy˙zszy program po kompilacji b˛edzie wygl ˛

adał tak:

;.asm

.chip 8052

;.endams

;char c1;

.internal_uninit_data

_c1: .ds 1

;

.program

_main: .equal $

;

?ASC0: .equal 0

?TSC0: .equal 0

?LSC0: .equal 1

inc sp

;c1=P0

mov a,.low. _P0

mov .low. _c1, a

25

background image

2

Programowanie w C µK rodziny Intel 8051

;c1=P1

mov a,.low. _P1

xch a,r0

mov a,sp

add a,#0-?LSC0-1

xch a,r0

mov @r0,a

;P2=c2

mov .low. _P2,a

;local c2

c2: .var+0-?LSC0+1

;asm

mov .low. _c1,p0

mov _c2,p1

;endasm

Komunikacje z bitami rejestrów specjalnych w programie w C. Program ten deklaruje rejestry
adresowane bitowo jako struktur˛e bitow ˛

a. Program w C:

#include “c8052sr.h”

extern struct special_functions_bits _SFB;

char c1;

main()

{

_SFB.EA=1;

}

po kompilacji:

;_SFB.EA=1

setb .low. __SFB+47

;

2.2.3

Deklaracja rejestrów roboczych

Kompilator C wykorzystuje wszystkie rejestry robocze r0 . . . r7 mikrokontrolera, niezb˛edne

jest wi˛ec ich zdefiniowanie w programie rozruchowym w sposób wła´sciwy dla kompilatora.
Najlepiej zrobi´c to w postaci sekcji rejestrowej. Jej parametry mo˙zna zadeklarowa ´c na poziomie
asemblera, bo nie ulegaj ˛

a one zmianie w trakcie konsolidacji. Realizowane to jest nast˛epuj ˛

aco:

registers:

.section reg, offset 0, ref_only

.global __reg0

.global __reg1

.

.

.

.global __reg7

26

background image

2.2

Program rozruchowy

__reg0:

.ds 1

.

.

.

__reg7:

.ds 1

__oper1_lsb: .equal __reg0

__oper1_msb: .equal __reg2 ;adres operandu 1

.

.

.

__stack_msb: .equal __reg7

2.2.4

Przesuwanie danych

Kompilator u˙zywa czterech rodzajów sekcji wraz z trzema odpowiadaj ˛

acymi im sekcjami

bibliotecznymi. Sekcje te nosz ˛

a ró˙zne nazwy dla trybu wewn˛etrznego i zewn˛etrznego kompila-

tora.

Rodzaj sekcji

Sekcje biblioteczna

Tryb zewn˛etrzny

program

lib_program

const_data

lib_const_data

init_data

lib_init_data

uninit_data

-

Tryb wewn˛etrzny

program

lib_program

internal_const_data

lib_internal_const_data

internal_init_data

lib_internal_init_data

internal_uninit_data

-

Pierwszy rodzaj sekcji zawiera programy u˙zytkownika i programy biblioteczne. Pozostałe

trzy rodzaje sekcji u˙zywane przez kompilator słu˙z ˛

a do lokowanie danych podzielonych na 3 klasy:

dane nieinicjowane, dla których w wyniku deklaracji typu musi by ´c zarezerwowane miej-
sce w pami˛eci, jednak w rezerwowany obszar nie s ˛

a wpisywane ˙zadne warto ´sci

dane inicjowane, którym prócz zadeklarowania typu przypisywana jest warto ´s´c. Obydwa
powy˙zsze typy zwi ˛

azane s ˛

a z deklaracjami zmiennych.

trzeci typ danych zwi ˛

azany jest ze stałymi u˙zywanymi w programie. Stałe nie zmieniaj ˛

a

warto´sci przez cały czas działania programu. Okre´slony symbol mo˙zna zadeklarowa´c jako
stał ˛

a u˙zywaj ˛

ac do tego celu słowa kluczowego

const

.

Przykład:

char c1;

char c2=0;

const char c3=3;

main(){}

27

background image

2

Programowanie w C µK rodziny Intel 8051

po kompilacji:

;char c1

.internal_uninit_data

_c1: ds 1

;char c2=0;

.internal_init_data

_c2: .byte 0

;const char c3=3;

.internal_const_data

_c3: .byte 3

Utworzenie w/w klas sekcji pozwala na umieszczenie modułów bibliotecznych w okre ´slonych
obszarach pami˛eci. S ˛

a one lokowane zgodnie z parametrami podanymi w pliku konsolidacji

(

*.lnk

). Program rozruchowy musi zdefiniowa´c wszystkie niezb˛edne sekcje, nawet je´sli s ˛

a

puste. Przyj˛ecie okre´slonego porz ˛

adku pozwala konsolidatorowi na wyznaczanie rozmiarów

sekcji, co jest niezb˛edne do przemieszczania odpowiednich sekcji przez program rozruchowy
oraz ewentualne zerowanie odpowiednich sekcji.

W funkcjach j˛ezyka C mog ˛

a wyst˛epowa´c dane tymczasowe, które spełniaj ˛

a wewn ˛

atrz funk-

cji zadania pomocnicze. Moduły biblioteczne przechowuj ˛

a ich warto ´sci na stosie. Lokalizacja

ka˙zdej zmiennej wskazywana jest jako przesuni˛ecie w stosunku do zawarto ´sci wska´znika chwi-
lowych zmiennych bibliotecznych
:

__ilib_temp_ptr

(dla trybu wewn˛etrznego). Wyznaczanie

lokalizacji dokonywane jest w trakcie kompilacji i wymaga zdefiniowania odpowiednich sek-
cji. Te sekcje nie mog ˛

a by przemieszczane wi˛ec ich parametry s ˛

a definiowane na poziomie

asemblera.

2.2.5

Przygotowanie stosu

Stos wewn˛etrzny umieszczany jest ponad obszarem wewn˛etrznych danych nieinicjowanych.

Niezb˛ednym elementem zwi ˛

azanym z tym obszarem jest wska´znik

__ilib_temp_ptr

słu˙z ˛

acy

do poruszania si˛e po zarezerwowanym obszarze pami˛eci, który programy biblioteczne u˙zywaj ˛

a

do przechowywania wyników. Mo˙zliwe jest wielokrotne wywoływanie podprogramów biblio-
tecznych realizowane w trzech krokach:

1. Lokalizacja kolejnego bloku danych w obszarze stosu o rozmiarze

__lib_temp_constants_size

.

2. Przechowanie warto´sci bie˙z ˛

acego wska´znika w

__ilib_temp_ptr

.

3. Wprowadzenie nowej warto´sci wska´znika i wywołanie programu bibliotecznego.

2.2.6

Wywołanie programu w C

Wywołanie programu w C z poziomu programu rozruchowego realizowane jest rozkazem

LCALL_MAIN

. Mo˙zna te˙z stosowa´c rozkaz skoku gdy nie przewiduje si˛e powrotu po zrealizo-

waniu programu w C. Gdy taki powrót ma miejsce (np. gdy wywołanie nast ˛

apiło z programu

28

background image

2.3

Organizacja danych w C

internal_init_data

internal_lib_init_data

__ilib_temp_ptr

internal_uninit_data

internal_lib_temp_constants

Bank 3

Bank 2

Bank 1

Bank 0

Bity stanu

30h

7Fh

00h

Rysunek 2.2: Struktura wewn˛etrznej pami˛eci RAM po zainicjowaniu stosu

monitora lub systemu operacyjnego) nale˙zy zapewni ´c przywrócenie warto´sci wska´znika stosu
jaka była przed wywołaniem programu w C.

2.3

Organizacja danych w C

2.3.1

Typy danych i ich modyfikatory

Kompilator 2500AD operuje na nast˛epuj ˛

acych typach danych:

Nazwa

Typ

Rozmiar

znakowy

char

8 bitów

całkowity

int

16 bitów

całkowity krótki

short

8 bitów

całkowity długi

long

32 bity

zmiennoprzecinkowy

float

32 bity (IEEE)

zmiennoprzecinkowy podwójnej precyzji

double

64 bity (IEEE)

Stosowane s ˛

a nast˛epuj ˛

ace kwalifikatory:

Kwalifikator

Stosowany do typu

unsigned

char, int, long

const

do wszystkich wł ˛

aczaj ˛

ac struktury

volatile

do wszystkich wł ˛

aczaj ˛

ac struktury

Znaczenie kwalifikatorów:

unsigned

liczba całkowita nieujemna. W stosunku do takich liczb obowi ˛

azuj ˛

a reguły arytme-

29

background image

2

Programowanie w C µK rodziny Intel 8051

tyki binarnej.

const

słu˙zy do wskazywania stałych, które nie podlegaj ˛

a zmianom w czasie realizacji

całego programu. Kompilator generuje kod pozwalaj ˛

acy na przekazywanie tych

danych do procesora. Zmienne wska´znikowe o warto´sciach b˛ed ˛

acych adresami do

tych stałych maj ˛

a długo´s´c 16 bitów.

volatile

wskazuje, ˙ze okre´slone dane musz ˛

a by´c ponownie ładowane przy ka˙zdym ich u˙zy-

ciu poniewa˙z s ˛

a modyfikowane w trakcie realizacji programu. Tego typu kwalifika-

tor jest u˙zyteczny przy obsłudze układów I/O adresowanych jednolicie z pami˛eci ˛

a.

Uwaga:

Standard j˛ezyka C wymaga oby argumenty operacji 2-argumentowej typy char były

najpierw przetworzone na posta´c int. Opisywany kompilator nie przestrzega tego wychodz ˛

ac

z zało˙zenia, ˙ze mikrokontorlery rodziny 8051 znacznie cz˛e´sciej wykonuj ˛

a operacje na liczbach

8-bitowych typu char ni˙z na 16bitowych typu int. Dlatego trzeba kontrolowa ´c efekty stosowa-
nych operacji. Ilustruje to przykład:

char c1,c2;

int i;

i=c1<<8; /* przesu´

n w lewo 8 pozycji */

Rezultat tej operacji wynosi 0 poniewa˙z wszystkie bity zostały przesuni˛ete przed przechowa-
niem wyniku w postaci zmiennej

i

. Aby uzyska ´c poprawny wynik przed przesuni˛eciem nale˙zy

dokona´c konwersji zmiennej

c1

na typ int:

i=(int)c1<<8;

2.3.2

Organizacja ramki stosu

Ka˙zdej funkcji kompilowanej w trybie wewn˛etrznym przydzielany jest fragment pami˛eci

zorganizowany w stos nazywany ramk ˛

a (rys. 2.3). Składa si˛e ona z trzech obszarów:

1. pami˛eci argumentów funkcji,

2. pami˛eci danych tymczasowych,

3. pami˛eci zmiennych lokalnych.

Kompilator dla ka˙zdej funkcji generuje trzy stałe procesu kompilacji, które stanowi ˛

a rozmiary

danych w ramce stosu:

?LSC

rozmiar danych lokalnych

?TSC

rozmiar danych tymczasowych

?ASC

rozmiar argumentów przekazywanych bezpo´srednio na stos

30

background image

2.3

Organizacja danych w C





Dane tymczasowe

Argumenty

Argumenty

Zmienne lokalne

SP po wywołaniu

funkcji

SP przed wywołaniem

funkcji

?ASC - rozmiar obszaru argumentow przekazy-

wanych bezpos´rednio przez stos

SP-?LSC

SP-?LSC+1-TSC

Argumenty przekazywane przez rejestry

?TSC - rozmiar danych tymczasowych

?LSC - rozmiar zmiennych lokalnych

Adres powrotu z funkcji (2 bajty)

Rysunek 2.3: Ramka stosu

Rozmiary te maj ˛

a warto´sci równe liczbie bajtów zarezerwowanych w ramce na dany rodzaj wiel-

ko´sci. Słu˙z ˛

a one do okre´slania wzgl˛ednych adresów bazowych obszarów ramki, które z kolei

stanowi ˛

a podstaw˛e wyznaczania poło˙zenia danych w ramce. Okre´slone s ˛

a nast˛epuj ˛

ace adresy

bazowe:

adres wzgl˛edny pocz ˛

atku obszaru zmiennych lokalnych (

-?LSC+1

) wskazuj ˛

acy poło˙zenie

najstarszego bajtu pierwszej zmiennej lokalnej wzgl˛edem aktualnej zawarto ´sci wska´znika
stosu

adres wzgl˛edny pocz ˛

atku obszaru danych tymczasowych (

-?LSC

)

adres wzgl˛edny ko ´nca obszaru danych tymczasowych (

-?LSC-?TSC

), który słu˙zy jako

adres bazowy obszaru argumentów funkcji

Powy˙zsze adresy bazowe umo˙zliwiaj ˛

a lokalizacj˛e danych w ramce na podstawie ich adresów

wzgl˛ednych b˛ed ˛

acych liczbami wskazuj ˛

acymi odległo´s´c w bajtach najstarszego bajtu danych

od adresu bazowego.

2.3.3

Przekazywanie argumentów do funkcji

Tłumacz ˛

ac funkcj˛e j˛ezyka C kompilator standardowo lokuje ich argumenty typu char i int

w rejestrach roboczych. W momencie gdy kompilator przetłumaczy wywołanie funkcji rozpo-
czyna poszukiwanie miejsca dla przechowania pierwszego argumentu. Je ´sli jest on typu char/int
i jest miejsce w rejestrach to jest on tam umieszczany. W przeciwnym przypadku argument jest
lokowany na stosie. Czynno´s´c ta powtarzana jest do wyczerpania listy argumentów. Kompilator

31

background image

2

Programowanie w C µK rodziny Intel 8051

u˙zywa rejestrów A, R1, R2, R3

4

do przechowywania argumentów typu char, oraz par R2+R0,

R3+R1 dla typu int. Przykłady:

funkcja1(char arg1, char arg2)

– pierwszy argument umieszczony jest w A, drugi w R2

funkcja2(char arg1, int arg2)

– pierwszy argument w A, drugi w R3+R1

funkcja3(int arg1, char arg2)

– pierwszy argument w parze R2+R0, drugi w R1

funkcja4(int arg1, int arg2)

– pierwszy w R2+R0, drugi R3+R1

Po przej´sciu do realizacji funkcji w pierwszym kroku wysyłane s ˛

a na stos argumenty przekazy-

wane w rejestrach. Po ich wysłaniu obszar ramki stosu przeznaczony na argumenty zawiera je
w kolejno´sci odwrotnej do kolejno´sci ich deklaracji. Pokazano to na rys. 2.4 dla przykładowej
funkcji:

f_przykl_1 (char, int, float)

Pamie˛c´ danych
tymczasowych

char

int

int

float

float

float

float

bity 0..7

bity 0..7

bity 8..15

bity 0..7

bity 8..15

bity 16..23

bity 24..31

Ostatni argument

Pierwszy argument

Rysunek 2.4: Kolejno´s´c argumentów funkcji w ramce stosu

Przekazanie argumentów na stos odbywa si˛e dwuetapowo:

1. Przed wywołaniem funkcji – pocz ˛

atkowe argumenty s ˛

a ładowane do rejestrów roboczych,

reszta na stos.

2. Po wywołaniu funkcji – argumenty z rejestrów przenoszone s ˛

a na stos.

Mi˛edzy tymi działaniami ma miejsce operacja zwi ˛

azana z wywołaniem podprogramu realizuj ˛

a-

cego dan ˛

a funkcj˛e. Dlatego obszar stosu wewn˛etrznego przeznaczonego na argumenty zostaje

przedzielony na dwie cz˛e´sci dwubajtowym adresem powrotu z podprogramu.

4

W tej kolejco´sci.

32

background image

2.3

Organizacja danych w C

Przykład:

main()

{

f_przykl_2(1,2,3);

}

f_przykl_2(int x, int y, int z)

{

int a,b,s;

a=4;

b=5;

s=0;

s=s+z;

s=s+y;

return(s);

}

Odwołanie si˛e do funkcji

f_przykl_2

wymaga przekazania do niej trzech argumentów. Argu-

menty pierwszy i drugi lokowane s ˛

a w parach rejestrów R2 i R0 oraz R3 i R1, trzeci argument

lokowany jest na stosie. Po kompilacji odpowiednie instrukcje asemblera maj ˛

a posta ´c:

;f_przykl_2(1,2,3)

mov

r0,#.low. 3

mov

r2,#.high. 3

push

_oper1_msb

push

_oper2_lsb

mov

r1,#.low. 2

mov

r3,#.high. 2

mov

r0,#.low. 1

mov

r0,#.high. 1

lcall _f_przykl_2

dec

sp

dec

sp

?BOF0:

.equal $

ret

_f_przykl_2: .equal $

push

_oper2_msb

push

_oper2_lsb

push

_oper1_msb

push

_oper1_lsb

Po wywołaniu podprogramu funkcji argumenty z rejestrów przenoszone s ˛

a na stos. Po zako ´n-

czeniu tej operacji ramka stosu ma posta´c przedstawian ˛

a na rys. 2.5.

2.3.4

Rozmieszczenie zmiennych lokalnych w ramce stosu

Zmienne lokalne umieszczane s ˛

a na stosie w kolejno´sci ich definiowania zaczynaj ˛

ac od naj-

starszego bajtu. Dla funkcji z przykładu ze strony 33 map˛e pami˛eci zmiennych lokalnych przed-
stawia rysunek 2.6.

33

background image

2

Programowanie w C µK rodziny Intel 8051

.low. 1

.low. 2

tymczasowych

Pamie˛c´ danych

Zmienne lokalne

.high. 1

.high. 2

adres

powrotu

.low. 3

.high. 3

Rysunek 2.5: Ramka stosu dla przykładu ze strony 33

.low. 0

Pamie˛c´ danych

tymczasowych

.high. 4

.high. 5

.low. 4

.low. 5

.high. 0

Rysunek 2.6: Mapa pami˛eci zmiennych lokalnych

34

background image

2.3

Organizacja danych w C

Rozmieszczenie zmiennych lokalnych musi by ´c poprzedzone zarezerwowaniem obszaru

stosu na dane tymczasowe i zmienne lokale. Odpowiedni fragment programu po kompilacji
ma posta´c:

?ASC1: .equal 2

?TSC1: .equal 0

?LSC1: .equal 6

mov a,sp

add a,#?TSC1+?LSC1

mov sp,a

;po tej operacji wska´

znik stosu wskazuje koniec ramki stosu

Mechanizm lokowanie zmiennych ilustruje poni˙zszy kod:

;a=4

mov a,sp

add a#0-?LSC1+1

mov r0,a

mov @r0,#.high. 4

inc r0

mov @r0,#.low. 4

;b=5

mov a,sp

add a,#2-?LSC1+1

mov r0,a

.

.

.

;s=0

.

.

.

Po zako ´nczeniu lokowania zmiennych lokalnych ramka stosu dla przykładu ze strony 33 przed-
stawion ˛

a na rysunku 2.7. W tej formie jest ona wykorzystywana przez cały czas realizacji pod-

programu funkcji.

Obszar zmiennych tymczasowych jest wykorzystywany w taki sam sposób jak obszar zmien-

nych lokalnych w miar˛e pojawiania si˛e danych wykorzystywanych chwilowo dla celów przecho-
wania wyników po´srednich.

Powrót z podprogramu funkcji wymaga ustawienia wska´znika stosu SP. Realizuj ˛

a to instruk-

cje:

;return(s)

?BOF1: .equal $

mov a,sp

add a,#-?LSC1-?TSC1-4

mov sp,a

ret

35

background image

2

Programowanie w C µK rodziny Intel 8051

.low. 0

Pamie˛c´ danych

tymczasowych

.high. 4

.high. 5

.low. 4

.low. 5

.high. 0

.low. 1

.high. 1

.low. 2

.high. 2

adres

powrotu

.low. 3

.high. 3

Rysunek 2.7: Mapa ramki stosu funkcji z przykłady ze strony 33

2.3.5

Przechowywanie warto ´sci zwracanych przez funkcj ˛e

Zmienna zwracana przez funkcj˛e okre´slona jest jako argument instrukcji

return

. Typ zwra-

canej warto´sci musi by´c wskazany przez podanie typu funkcji przed jej nazw ˛

a. Pomini˛ecie tej

deklaracji oznacza funkcj˛e etapu int (czyli zwracaj ˛

ac ˛

a warto´s´c całkowit ˛

a). Sposób zwracania

warto´sci funkcji okre´sla tablica:

Typ zwracanej warto´sci

Zwracana w:

wszystkie funkcje:

char

A

int

R2,R0

funkcje zewn˛etrzne (korzystaj ˛

ace z zewn˛etrznej pami˛eci RAM):

long, float, double

lokacja w pami˛eci tymczasowej:

__FUNCTION_RET_ADDR

wska´znik do lokacji w R2 i R0

funkcje wewn˛etrzne:

long, float, double

lokacja w pami˛eci tymczasowej:

__IFUNCTION_RET_ADDR

wska´znik do lokacji w A

Sposób zwracania warto´sci przez funkcj˛e z przykładu ze strony 33 pokazuje fragment pro-

gramu:

mov a,sp

mov a,#4-?LSC1+1

mov r1,a

mov @r1,__oper1_msb

inc r1

mov @r1,__oper1_lsb

36

background image

2.4

Przekazywanie danych mi˛edzy funkcjami a instrukcjami asemblera

;return(s)

.

.

.

Modyfikacja funkcji z tego przykładu powoduje, ˙ze zwracana jest warto ´s´c 4-bajtowa. Program
w C ma wówczas posta´c:

main()

{

long f_przykl_3(1,2,3);

}

long f_przykl_3(int x, int y, int z)

{

int a,b;

long s;

a=4;

b=5;

s=(long)z;

return(s);

}

Po przetłumaczeniu funkcji return:

;return(s)

mov r1,a

mov a,__ilib_temp_ptr

add a,#-__IFUNCTION_RET_ADDR

lcall __istore_long

2.4

Przekazywanie danych mi ˛edzy funkcjami a instrukcjami

asemblera

2.4.1

Wprowadzanie instrukcji asemblera do programu w C

Współprac˛e fragmentów programów w C i w asemblerze umo˙zliwiaj ˛

a odpowiednie dyrek-

tywy kompilatora. Podstawow ˛

a konstrukcj ˛

a składniow ˛

a umo˙zliwiaj ˛

ac ˛

a wprowadzenie instrukcji

asemblera jest para dyrektyw:

.asm

.

;program w asemblerze

.

.endasm

Tekst mi˛edzy nimi jest przenoszony przez kompilator bezpo´srednio do tłumaczenia przez asem-
bler.

37

background image

2

Programowanie w C µK rodziny Intel 8051

Uwaga:

Kompilator dzieli etykiety na lokalne i globalne:

nazwy lokalne generowane s ˛

a przez kompilator wewn ˛

atrz funkcji i s ˛

a wa˙zne tylko w ob-

r˛ebie danej funkcji,

nazwy globalne musz ˛

a by´c definiowane na zewn ˛

atrz funkcji.

Nazwy lokalne definiowane wewn ˛

atrz funkcji wyró˙zniane s ˛

a przez kompilator znakiem

?

na

pocz ˛

atku lub ko ´ncu nazwy. Poniewa˙z stosowana jest zasada, ˙ze u˙zycie nazwy globalnej ko ´nczy

blok nazw lokalnych we wstawkach asemblerowych nale˙zy u˙zywa ´c nazw z

‘?’

na pocz ˛

atku lub

na ko ´ncu.

2.4.2

Dost ˛ep do zmiennych lokalnych

Zmienne lokalne umieszczane s ˛

a na stosie wewn˛etrznym lub zewn˛etrznym w zale˙zno ´sci od

trybu pracy kompilatora. Kompilator lokalizuje je w sposób wzgl˛edny w odniesieniu do war-
to´sci wska´znika ramki. Dyrektywa

.local

powoduje wygenerowanie na poziomie asemblera

dyrektywy

.var

przyporz ˛

adkowuj ˛

acej zmiennej warto´s´c b˛ed ˛

acej przesuni˛eciem w stosunku do

aktualnej zawarto´sci wska´znika ramki. W trybie wewn˛etrznym rol˛e wska´znika ramki spełnia
SP. Poni˙zszy przykład ilustruje wykorzystanie dyrektywy

.local

do wskazywania z poziomu

asemblera zmiennej lokalnej przez nazw˛e:

main()

{

char c2;

int int2;

.local c2; /* tworzy przesuni˛

ecie w stosunku do zawarto´

sci SP */

.local int2;

/* teraz asembler mo˙

ze odwoływa´

c si˛

e do obu zmiennych przez nazw˛

e */

.asm

;wstawka asmeblerowa

mov a,sp

add a,#c2

mov r0,a

mov @r0,#0

;wyzeruj zmienn ˛

a c2

mov a,sp

add a,#int2

mov r0,a

mov @r0,#.high. 0

;wyzeruj zmienn ˛

a int2

inc r0

mov @r1,#.low. 0

.endasm

}

2.4.3

Dost ˛ep do argumentów funkcji j ˛ezyka C

Dost˛ep do argumentów funkcji j˛ezyka C z poziomu asemblera umo˙zliwia dyrektywa kom-

pilatora

.arg

. Działa ona tak samo jak dyrektywa

.local

z tym, ˙ze argumentem generowanej

38

background image

2.4

Przekazywanie danych mi˛edzy funkcjami a instrukcjami asemblera

dyrektywy asemblera

.var

jest przesuni˛ecie wskazuj ˛

ace zmienn ˛

a w obszarze argumentów funk-

cji. Przykład:

main(char c1, int int1)

{

.arg c1;

.arg int1;

/* dalej ja w przykładzie powy˙

zej */

}

2.4.4

Adresowanie bezpo ´srednie i po ´srednie w programach w C

Adresowanie bezpo´srednie – za nazw ˛

a u˙zywan ˛

a w programie kryje si˛e adres, tzn. u˙zycie

danej nazwy powoduje odwołanie si˛e do komórki pami˛eci (lub rejestru) opatrzonej nazw ˛

a. Do-

tyczy to wszystkich nazw globalnych takich jak:

nazwy zmiennych globalnych

nazwy funkcji

nazwy rejestrów specjalnych (s ˛

a definiowane z zasady jako nazwy globalne)

a tak˙ze (z zało˙zenia) struktur zło˙zony takich jak:

tablice

unie

Przykład:

const char tab[]=”komunikat 1”;

main ()

{

extern const char tab[];

char c1;

c1=tab[0];

}

fragment odpowiedniego programu asemblerowego:

.internal_const_data

_tab:

.byte

”komunikat 1”

.program

_main:

.equal $

?ASC0:

.equal 0

?TSC0:

.equal 0

?LSC0:

.equal 1

39

background image

2

Programowanie w C µK rodziny Intel 8051

;c1=tab[0]

mov

dptr,#_tab+0

clr

a

movc a,@a+dprt

xch

a,r0

mov

a,sp

add

a,#0-?LSC0+1

xch

a,r0

mov

@r0,a

?BOFO:

.equal $

dec

sp

ret

.global _tab

.global _main

.extern _tab

.end

U˙zywaj ˛

ac nazw operuje si˛e na zawarto´sciach komórek lub rejestrów traktowanych jako argu-

menty o danej nazwie. Mo˙zliwe jest te˙z uzyskanie adresu danej nazwy i odwołanie si˛e do
argumentu po´sredniego przez ten adres. Mo˙zliwe s ˛

a równie˙z stosowne operacje na adresach

jako zmiennych całkowitych. Przykład:

char c1=1;

main()

{

extern char c1;

int adr_main;

adr_main=&main;

c1++;

}

po kompilacji:

;char c1=1

.internal_init_data

_c1:

.byte 1

.program

_main: .equal $

?ASC0:

.equal 0

?TSC0:

.equal 0

?LSC0:

.equal 4

mov a,sp

mov a,#?TSC0+?LSC0

mov sp,a

40

background image

2.4

Przekazywanie danych mi˛edzy funkcjami a instrukcjami asemblera

;adr_main=&main

mov r0,#.low. _main

mov r2,#.high. _main

mov a,sp

add a,#2-?LSC0+1

mov r1,a

mov @r1,__oper1_msb

inc r1

mov @r1,__oper1_lsb

;c1++

inc .low. _c1

Adresowanie po´srednie – polega na operowaniu adresem zmiennej zamiast jej nazw ˛

a. Tego ro-

dzaju działanie jest niezb˛edne je´sli chce si˛e mie´c dost˛ep do zmiennej jednej funkcji z poziomu
innej funkcji. Przekazywanie argumentu z pierwszej funkcji do drugiej odbywa si˛e poprzez war-
to´s´c, tzn. przy u˙zyciu stosu przekazywane s ˛

a kopie argumentów funkcji wywołuj ˛

acej. Funkcja

wywołana operuje tylko na tych kopiach. Aby mo˙zna było zmieni ´c oryginały argumentów funk-
cja wywołuj ˛

aca musi przekaza´c ich adresy. Umo˙zliwia to operator

&

, który u˙zyty dla zmiennej

o nazwie ”

a

” w sposób ”

&a

” nakazuje pobranie adresu zmiennej

a

. Chc ˛

ac teraz operowa ´c na

tym adresie mo˙zna utworzy´c now ˛

a zmienn ˛

a, np. ”

prt=&a;

” nazywan ˛

a wska´znikiem (zmienn ˛

a

wska´znikow ˛

a), której warto´s´c stanowi adres zmiennej

a

. Chc ˛

ac zmieni´c warto´s´c zmiennej

a

mo˙zna zastosowa´c ten wska´znik z operatorem ”

*

” nakazuj ˛

acym traktowa ´c swój argument jako

adres, np. ”

*ptr=5;

” powoduje, ˙ze zmienna

a

przyjmuje warto´s´c 5.

41

background image

2

Programowanie w C µK rodziny Intel 8051

42

background image

Indeks

adres bazowy, 10
asembler, 1

biblioteki, 9
bie˙z ˛

acy wska´znik umieszczenia, 5

dyrektywa, 2

.ABSOLUTE, 12
.BSECT, 14
.CODE, 14
.COMMENT, 3
.DATA, 14
.DB, 6
.DS, 7
.DW, 6
.ELSE, 8
.END, 7
.ENDIF, 8
.ENDM, 8
.ENDMOD, 9
.EQU, 6
.EXTERNAL, 13
.GLOBAL, 13
.IF, 8
.INCLUDE, 14
.MACRO, 8
.MOD, 9
.ORG, 5, 12
.RADIX, 4
.RELATIVE, 12
.RSECT, 14
.SECTION, 15
.SET, 6

grupy sekcji, 10

instrukcja, 2

kompilacja, 22

makroasembler, 7
makrodefinicja, 8

parametry

aktualne, 8
formalne, 8

wywołanie, 8

moduł, 9

konsolidacja, 9
posta´c relokowalna, 9

nazwy, 3, 4

absolutna, 12
absolutne, 6
atrybuty, 6, 13

absolutno´sci, 12
globalno´sci, 13
okre´slono´sci, 6
zewn˛etrzno´sci, 13

globalne, 13
relokowalna, 12
wspólne, 13
zewn˛etrzne, 13

pole

argumentów, 3
etykiety, 2
komentarza, 3
operacji, 3

procedura, 9
program

´zródłowy, 1

wynikowy, 1

program rozruchowy, 22
przeł ˛

acznik sekcji, 15

słownik, 5

dopisywanie nazw, 5

segment, 9, 14

43

background image

Indeks

sekcja, 9, 14

bezpo´srednia, 16
bitowa, 15
definiowanie, 15
domy´slna, 14
lokowanie, 16
po´srednia, 16
pusta, 16
refernecyjna, 16
rejestrowa, 15
standardowa, 14

.BSECT, 14
.CODE, 14
.DATA, 14
.RSECT, 14

u˙zytkownika, 14

stałe, 3

liczbowe, 4
znakowe, 4

wyra˙zenia arytmetyczne, 3

operacje porówna ´n, 5
operatory, 4

44


Wyszukiwarka

Podobne podstrony:
Podst wskazniki makro dla Polsk Nieznany
instrukcja bhp dla materialow w Nieznany
Projekt bazy danych dla Przycho Nieznany
Planowanie programu dla zdrowia Nieznany (4)
Luksusowe opakowanie dla wyjatk Nieznany
Karto Topo sciaga wersja dla am Nieznany
p 1196 zakres tematyczny dla wf Nieznany
ANDEROL srodki smarne dla przem Nieznany (2)
Moralne przeslanie JP II dla pi Nieznany
instrukcja bhp dla pomieszczen Nieznany
Planowanie programu dla zdrowia Nieznany
Ogrz cw 1 2 3 i 4 dla stu124481 Nieznany
Planowanie programu dla zdrowia Nieznany (5)
elektrownie wiatrowe dla domu i Nieznany

więcej podobnych podstron