42173 Image97 (3)

42173 Image97 (3)



Programowanie

ABC... GCC Pisanie funkcji w pełnym asemblerze

WinAV'R umożliwia nam pisanie całych funkcji w asembierzc. Pliki zawierające kod w asemblerze powinny być zapisane z roz szerzeniem .S (duża litera S). Niezależnie od tego, że system Windows nie rozróżnia dużych i małych liter, dla naszego kompilatora ma to znaczenie.

Wszystko co da się zrobić, pisząc funkcję w asemblerze, da się również zrobić za po mocą wstawek asemblerowych. Jednak wstawki takie nie są wygodne do pisania i uruchamiania. Pisząc oddzielny plik, otrzymamy możliwość kolorowania składni, a jeśli w kodzie pojawi się błąd, zostaniemy poinformowani dokładnie, której linii dotyczy.

Kompilacja plików asemblera

Aby kompilator AVR-GCC zauważył i skompilował nasz plik asemblerowy, musimy dodać go w odpowiednim miejscu do pliku makefile. Robimy to w identyczny sposób, w jaki dodawaliśmy pliki źródłowe C. Teraz jednak zapisujemy je w innym miejscu: ASRC « BOOtllb.S

Rejestry

Gdy piszemy cały program w asemblerze, możemy korzystać z rejestrów według uznania. Gdy korzystamy jednocześnie z kompilatora C, musimy podporządkować się stosowanym przez niego regułom. Zanim więc zaczniemy cokolwiek pisać, zapoznamy się ze znaczeniem poszczególnych rejestrów. rO - rejestr tymczasowy. Jego wartość może być stracona w każdym punkcie kodu poza przerwaniami, które odtwarzają jego zawartość, rl powinien zawsze zawierać 0. Może jednak być wykorzystany do dowolnego celu, pod warunkiem że przed skończeniem działania funkcji zostanie wyzerowany. Przerwania zapamiętują i odtwarzają jego wartość. r2-rl7 oraz r28-r29 (wskaźnik Y) kompilator może używać ich dla danych lokalnych. Funkcje napisane w asemblerze są odpowiedzialne za odzyskanie zawartości niszczonych rejestrów przed zakończeniem swojego działania.

r!8-r27 oraz r30-r31 (wskaźnik Z) - kompilator może używać ich dla danych lokalnych. Jednak teraz to wywołująca funkcja jest odpowiedzialna za zapamiętanie i odzyskanie rejestrów zawierających ważne informacje. Dla nas oznacza to, że tworząc funkcję w asemblerze, możemy swobodnie korzystać z wymienionych rejestrów, nie przejmując się odzyskiwaniem ich wartości.

Wywoływanie funkcji Funkcja od strony kodu maszynowego to podprogram wywoływany instrukcją cali. Parametry do niej przekazywane są w rejestrach, koleino od r25 do rS. Wszystkie

argumenty, nawet 8-bitowe, są wyrównane aby zaczynać się w rejestrach o parzystych numerach. To pozorne marnotrawstwo umożliwia jednak efektywne korzystanie z instrukcji ló-bitowych, jak movw. Dane 16-, 32- oraz 64-bitowc rozmieszczane są tak, że najbardziej znacząca częśc znajduje się w rejestrze o najwyższym numerze. Argumenty, które me zmieszczą się w rejestrach, umieszczane są na stosie.

Funkcje zwracają wartość poprzez rejestry r25-rl8. Dane także są wyrównane, co oznacza, że zwracana wartość 8-bitowa jest umieszczana w rejestrze r24.

Uwaga: Jeśli zwracana jest zmienna 8-bitowa, funkcja wywołująca rozszerza ją do 16 bitów. Jeśli jest to zmienna bez znaku, rejestr r25 zostanie zawsze wyzerowany. Jeśli jednak r24 zawiera zmienną ze znakiem, zawartość r25 zależy od znaku liczby zapisanej w r24: Oxtf dla liczby ujemnej i 0 dla liczby dodatniej. Tak więc liczba zc znakiem wymaga większej ilości kodu.

Aby funkcja była widoczna na zewnątrz

W asemblerze nadajemy nazwę funkcji poprzez nazwę etykiety. Aby etykieta była widoczna na zewnątrz, w powstającym pliku kodu relokowalncgo (*.o) należy wprowadzić dodatkową linię, informującą kompilator o takiej potrzebie. Robimy to za pomocą dyrektywy .global nazwa_ctykicty. Dopiero wtedy daną funkcję można wywołać z zew nątrz.

Należy pamiętać także o deklaracji odpowiedniej funkcji. Tutaj uwaga: kompilator nie będzie w stanie sprawdzić, czy deklaracja argumentów jest prawidłowa, jest lo dla niego jedyna informacja o tym, jak wywołać funkcję asemblerową.

Aby funkcja zewnętrzna była widoczna

Możemy działać także w dnigą stronę wywoływać z poziomu asemblera funkcje C. Aby zrobić to z poziomu asemblera, musimy umieścić dyrektywę .extem nożnaJtmkcji. Funkcję taką wywołujemy instrukcją cali. wcześniej umieszczając w rejestrach niezbędne parametry. Pamiętajmy także o zapamiętaniu rejestrów rl 8-r27 oraz wskaźnika Z. jeśli zawierają ważne dla nas dane. Preprocesor C

Kompilacja plików asemblera jest domyślnie tak skonfigurowana, żc zanim przeprowadzona zostanie właściwa kompilacja, plik przepuszczany jest przez preprocesor języka C. Daje nam to bardzo unikalne możliwości. Możemy używać komentarzy zarówno takich jak w C (/**/ oraz // do końca linii), jak i asemblerowych (: do końca linii). Ponadto możemy stosować znane nam dyrektywy, takie jak #include, ^dcfinc, #if -#else - #endif...

Zanim zaczniemy pisać kod w pełnym asemblerze, proponuję niewielką zmianę ustawień Programmers Notepad ’a. Odpowiednią opcję znajdziemy wywołując komendę Taols->Options. Resztę pokazuje rysunek 54.

Ciąg dalszy na stronie 47

Listing 157 Początek pliku Boot.ib.S #i ndi.de <avr/io.h> tfincltde „harddef.h"

// Dostęp do zmiennej globalnej

,extern g_pagcbuff

i/ ustawienia adefine boctlib_autoerasf //#define bootlib_autocheck // Zwracane wartości frdefine OJTintH_reg r25 tfdefine OJTintl_reg r?4 // Rejestry nicodzyskiwane // (rl8-r27, r30-r31) rtdefine templ rl8 4define pagelnop r19

//////////////////////////////

// void Do_SPM(uint8_t SPMYal) #define S3Mva1_reg r24 • giobol Do__SPM

lojspm:

// Czekanie na pan. FLASH

Co_S?M_waitspm:

Ids templ, SPMCR Sbrc terapl, SPMEN rjrap Do_SPM_wait3pcn // Czekanie na pam. EEPROM Co_3?M_*a_tee:

SblC _SFR_ID_ADDR(EECR), EEWS rjnp Do_SPM_waitee // Sekwencja SPM StS SPMCR, SFMvdl_iey

spm

// Powrót ret

Listing 158 Fragment funkcji Do_ WritcPagc #define WP_FlashAdrt;sH_reg r25 #define WP_FlashAdresL_reg r24 .global Do_WritePage Do_WritcPagc:

// Zabezpieczenie rej. Y push YL push YH

// Adres Flash do wskaźnika movw ZL, WP_FlćshAdresL_rec // Adres RAM do wskaźnika Idi YL, loG(g__p<agebuf £)

Idi yh, hi8(g_pagebuft) (...)

// Zwracam 0

clr OUTintH_reg Clr 0UrintlTreq rjmp WritsPage__end WcitePage_Errox:

Id1 0UTintL_reg, lo8(-l)

Idi 0UTintH_reg, hi8(-l):

// Odzyskiwanie danych W ł ittPdya_eiid;

clr rl pop YH pop YL

ret


44 Październik 2006 Elektronika dla Wszystkich


Wyszukiwarka

Podobne podstrony:
38347 Image96 (4) Programowanie ■ Programowanie ■ Listing J OJ modyf ikacjo funkcji h» led GetSpec S
skanuj0067 (22) sk: realizowane : osób przekazy- .tuacji, gdy cel est programem, "a do pis
Tabela . Języki programowania a główne paradygmaty języki paradygmaty asemblery,
Panel 2 Programy do Pisania rcMEfferfi
Poznaj C++ w$ godziny0081 Funkcje 67 Program wraca do funkcji main(), do linii 13. Okazuje się, że w
Program do minimalizacji funkcji logicznej metodą Quine-McCluskey. Autor: Paweł JanikTabela posortow
70341 zal 07 4 Studia zaoczne, 2006/2007 Zestaw 1 14. Co będzie jeśli w powyższym programie usuniemy

więcej podobnych podstron