Photo Rating Website
Home Maximum R The Cambr 0877 Ch09 Niewolnica

[ Pobierz całość w formacie PDF ]

można zwracać struktury. Po powrocie, RAX będzie zawierał przekazany adres
" w kolejnym wolnym rejestrze z grupy RAX, RDX, jeśli klasa jest całkowita
" w kolejnym wolnym rejestrze z grupy XMM0, XMM1, jeśli klasa to SSE
" w górnej części ostatniego używanego rejestru SSE, jeśli klasa to SSEUP
" w ST0, jeśli klasa jest zmiennoprzecinkowa
" razem z poprzednią wartością w ST0, jeśli klasa to X87UP
" część rzeczywista w ST0, a część urojona w ST1, jeśli klasa jest zespolona
Polecam do przeczytania x64 ABI (np. dokument x64-abi.pdf, do znalezienia w Internecie).
Dołączanie modułów (te napisane w asemblerze muszą być uprzednio skompilowane) odbywa się na linii
poleceń, z tym że tym razem możemy użyć samego kompilatora, aby wykonał za nas łączenie (nie musimy
uruchamiać linkera).
No to krótki 32-bitowy przykładzik (użyję NASMa i Borland C++ Builder):
Bogdan Drozdowski 99
Bogdan Drozdowski Język asembler dla każdego 2009-02-25
; NASM casm1.asm
section .text use32
global _suma
_suma:
; po wykonaniu push ebp i mov ebp, esp:
; w [ebp] znajduje się stary EBP
; w [ebp+4] znajduje się adres powrotny z procedury
; w [ebp+8] znajduje się pierwszy parametr,
; w [ebp+12] znajduje się drugi parametr
; itd.
%idefine a [ebp+8]
%idefine b [ebp+12]
push ebp
mov ebp, esp
mov eax, a
add eax, b
; LEAVE = mov esp, ebp / pop ebp
leave
ret
oraz plik casm.c:
#include
extern int _suma (int a, int b); /* deklaracja funkcji zewnętrznej */
int suma (int a, int b); /* prototyp funkcji */
int c=1, d=2;
int main()
{
printf("%d\n", suma(c,d));
return 0;
}
Kompilacja odbywa się tak:
nasm -o casm1.obj -f obj casm1.asm
bcc32 casm.c casm1.obj
Uwaga: w kompilatorach GNU: DJGPP, Dev-C++, MinGW, CygWin format wyjściowy NASMa powinien
być ustawiony na COFF. Możliwe, że format COFF trzeba będzie wybrać także w innych.
W wyniku otrzymujemy programik, który na ekranie elegancko wyświetla wynik równy 3.
Może się zdarzyć też, że chcemy tylko korzystać z funkcji języka C, ale główną część programu chcemy
napisać w asemblerze. Nic trudnego: używane funkcje deklarujemy jako zewnętrzne (pamiętając o znaku
podkreślenia), ale uwaga - swoją funkcję główną musimy nazwać _main. Jest tak dlatego, że teraz punkt
startu programu nie jest w naszym kodzie, lecz w samej bibliotece języka C. Program zaczyna się między
innymi ustawieniem tablic argumentów listy poleceń i zmiennych środowiska. Dopiero po tych operacjach
100 Bogdan Drozdowski
2009-02-25 Język asembler dla każdego Bogdan Drozdowski
biblioteka C uruchamia funkcję _main instrukcją CALL.
Inną ważną sprawą jest to, że naszą funkcję główną powinniśmy zakończyć instrukcją RET (zamiast
normalnych instrukcji wyjścia z programu), która pozwoli przekazać kontrolę z powrotem do biblioteki C,
umożliwiając posprzątanie (np. wyrzucenie buforów z wyświetlonymi informacjami w końcu na ekran).
Krótki (także 32-bitowy) przykładzik:
section .text
global _main
extern _printf
_main:
; printf("Liczba jeden to: %d\n", 1);
push dword 1 ; drugi argument
push dword napis ; pierwszy argument
call _printf ; uruchomienie funkcji
add esp, 2*4 ; posprzątanie stosu
; return 0;
xor eax, eax
ret ; wyjście z programu
section .data
napis: db "Liczba jeden to: %d", 10, 0
Kompilacja powinna odbyć się tak:
nasm -o casm2.obj -f obj casm2.asm
bcc32 casm2.obj
Jedna uwaga: funkcje biblioteki C mogą zamazać nam zawartość wszystkich rejestrów (poza EBX, EBP, ESI,
EDI w systemach 32-bitowych, i RBX, RBP, R12, R13, R14, R15 na systemach 64-bitowych), więc nie
wolno nam polegać na zawartości rejestrów po uruchomieniu jakiejkolwiek funkcji C.
Kompilator GNU gcc wymaga osobnego wytłumaczenia. Składnia wstawek asemblerowych różni się od
powyższej dość znacznie, a jej opisy możecie znalezć w podręczniku GCC (sekcje: 5.34 i 5.35), na stronach
DJGPP oraz (w języku polskim) na stronie pana Danileckiego.
Jak zauważycie, różni się nawet sam wygląd instrukcji, gdyż domyślnie gcc używa składni AT&T języka
asembler. U siebie mam krótkie porównanie tych składni.
Fortran 77
W tym języku nie wiem nic o wstawkach asemblerowych, więc przejdziemy od razu do łączenia modułów.
Fortran dekoruje nazwy, stawiając znak podkreślenia PO nazwie funkcji lub zmiennej (wyjątkiem jest funkcja
główna - blok PROGRAM - która nazywa się MAIN__, z dwoma podkreśleniami). [ Pobierz całość w formacie PDF ]

  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • spartaparszowice.keep.pl
  • Naprawdę poczułam, że znalazłam swoje miejsce na ziemi.

    Designed By Royalty-Free.Org