Dyskusja:Asembler x86/Łączenie z językami wysokiego poziomu/Moduły w języku C++
Zgodnie z założeniem muszę jeszcze napisać kod źródłowy w C ładujący te bibliotekę, ale nie jestem orłem w tym języku zatem jakby ktoś mógł to niech przepisze to z C++ i wrzuci tutaj. W najgorszym przypadku sam to zrobię, ale ja mam uraz do funkcji printf() i scanf() - Doles
- Hmm, zrobiłeś zasadniczy błąd. Linkowanie dynamiczne w zasadzie niczym nie różni się od statycznego. To oznacza, że wcale nie musisz używać dlfcn.h, żeby załadować dany program i powiązaną z nią bibliotekę - system powinien zrobić to za Ciebie. Mało tego, żeby załadować za pomocą dlfcn.h cokolwiek nie musisz się zbytnio wysilać. Popatrz na ten program (w C, żeby nie było :P):
#include <stdio.h>
#include <dlfcn.h>
unsigned int (*fun)(unsigned int, unsigned int);
int main ()
{
void *Biblioteka;
Biblioteka = dlopen("./sumuj.so", RTLD_LAZY); /* ja sobie nazwałem plik sumuj.asm -
u Ciebie nie musi tak być */
*(void **)(&fun) = dlsym(Biblioteka, "sumuj");
printf ("2+3=%d\n", (*fun)(2,3));
dlclose(Biblioteka);
return 0;
}
- ps. ten program kompiluje się normalnie, tj. przy użyciu komendy gcc plik.c -o plik --Kj 16:43, 11 lut 2008 (CET)
Nie wiem jak dla mnie jest spora różnica między linkowaniem statycznym a dynamicznym.W statycznym od razu dołączam całość pliku *.a bez względu na to czy ja wykorzystam jego funkcje (ich definicje czy nie). W linkowaniu dynamicznym tak jak przy pomocy dlfcn.h dołączam daną bibliotekę współdzieloną tylko wtedy gdy kod mojego programu ją wywoła. Te wszystkie dlopen`y i inne "gady" mogą się w ogóle nie wywołać (de facto nie uruchomić biblioteki współdzielonej) jeśli umieszczę je gdzieś w instrukcji np IF albo wywołując inną funkcję. Ale już nie raz mi udowodniłeś, że masz rację i znasz się na rzeczy lepiej niż ja :)Jak masz jakieś namiary na dokumentacje na ten temat to daj linka poprawie to i tamto. A propos kompilacji to w C++ miałem errory jak nie dałem "-ldl". A tam jedna flaga w tą czy w tamtą stronę :P No i za wiele się nie wysilałem z dlfcn tylko mnie te rzutowania przerastają... PS: Nie chcesz chyba powiedzieć teraz, że cały rozdział jest do bani ? :)- Doles
- Rozdział nie jest do bani - jest dobry, tyle, że trochę przesadziłeś z tymi bibliotekami dynamicznymi. Trochę przekroczyłeś zagadnienie :P. Odnośnie linkowania - nie chcę przepisywać z Wikipedii całego zagadnienia ;). --Kj 20:34, 15 mar 2008 (CET)
- Może dodam przy okazji przykład, jak naprawdę wygląda linkowanie dynamiczne. Oto kod programu w języku C oraz w GNU as (takie zboczenie :P).
#include <stdio.h>
unsigned int sumuj (unsigned int, unsigned int);
int main ()
{
printf ("2+3=%d\n", sumuj(2,3));
return 0;
}
- nazwijmy sobie ten plik jako test.c, następnie plik z biblioteką w asemblerze (pozwoliłem sobie obciąć wypisywanie tekstu na ekranie :P), niech się ona nazywa sumuj.S
.text
.globl sumuj
sumuj:
/* WPROWADZENIE:
[EBP+12] - pierwszy argument od prawej
[EBP+8] - drugi od prawej
[EBP+4] - adres powrotu z funkcji
[EBP] - stara wartość EBP
PRZYKŁAD DEKLARACJI FUNKCJI W C++ (przy linkowaniu statycznym)
int sumuj(int a, int b), zatem:
[EBP+12] = b
[EBP+8] = a
*/
pushl %ebp /* tworzymy ramkę stosu */
movl %esp,%ebp /* niech EBP ma teraz wartość ESP */
movl 0x0c(%ebp),%eax /* pobranie pierwszego argumentu od prawej strony */
addl 0x08(%ebp),%eax /* pobranie drugiego argumentu */
leave
ret /* koniec funkcji */
.size sumuj,.-sumuj
- teraz ważna rzecz: kompilacja
$ as sumuj.S -o sumuj.o $ ld -shared sumuj.o -o libsumuj.so # mv ./libsumuj.so /lib $ gcc test.c -o test -lsumuj $ ./test
- powinno wypisać "2+3=5". Oczywiście przenoszenie biblioteki do katalogu /lib wykonujemy jako root. Zwróć uwagę na linijkę .size sumuj,.-sumuj. Informacja o rozmiarze funkcji jest niezbędna do prawidłowego funkcjonowania linkera dynamicznego. Nie wiem, jak to działa pod NASM-em (leń ze mnie - nie chce mi się sprawdzać :P). Pozdrawiam --Kj 20:57, 15 mar 2008 (CET)
- Z pewnością przekroczyłem zagadnienie i sądzę, że niepotrzebnie wdałem się w szczegóły ale przynajmniej będzie rozdział (względnie) wyczerpujący :) -- Doles 19:44, 23 mar 2008 (CET)