Natrafiłem na fragment kodu void *p = &&abc;
. Jakie ma to znaczenie &&
? Wiem o odwołaniach do wartości r, ale myślę, że &&
w tym kontekście jest inaczej. Co to &&
oznacza void *p = &&abc;
?
Natrafiłem na fragment kodu void *p = &&abc;
. Jakie ma to znaczenie &&
? Wiem o odwołaniach do wartości r, ale myślę, że &&
w tym kontekście jest inaczej. Co to &&
oznacza void *p = &&abc;
?
Odpowiedzi:
&&
to rozszerzenie gcc służące do pobierania adresu etykiety zdefiniowanej w bieżącej funkcji.
void *p = &&abc
jest nielegalne w standardowym C99 i C ++.
To kompiluje się z g ++.
void*
.
__forceinline
? __declspec(naked)
? Jednym z moich ulubionych MSVCism jest:, template<typename T> class X { friend T; }
który jest nieprawidłowy w C ++ 03.
To adres etykiety i jest to funkcja specyficzna dla GCC .
int main(void) {
void* startp;
s:
startp = &&s;
printf("the assignment above starts at address %p\n", startp);
return 0;
}
Mogłeś się tego dowiedzieć, testując:
int main(void) {
void* startp;
int a;
startp = &&a;
printf("startp=%p\n", startp);
return 0;
}
W takim przypadku GCC mówi:
błąd: etykieta „a” używana, ale nie zdefiniowana
Musisz znać asemblera, aby naprawdę to zrozumieć, ale spróbuję ci wyjaśnić, co oznacza adres etykiety.
Po załadowaniu przez system operacyjny pliku .exe z dysku, składnik systemu operacyjnego zwany „programem ładującym” (system Windows ma „moduł ładujący PE”, linux ma „moduł ładujący ELF” lub może nawet inne, jeśli są one skompilowane w jądro), dokonuje „wirtualizacji” tego programu, zamieniając go w proces.
Ten proces uważa, że jest jedynym w pamięci RAM i ma dostęp do całej pamięci RAM (to znaczy 0x00000000-0xFFFFFFFF na komputerze 32-bitowym).
(powyższe to tylko krótki przegląd tego, co się dzieje, naprawdę musisz nauczyć się montażu, aby w pełni to zrozumieć, więc bądź ze mną)
Otóż etykieta w kodzie źródłowym jest w zasadzie adresem. „goto label”; nie robi nic poza skokiem do tego adresu (pomyśl o wskaźniku instrukcji w asemblerze). Ta etykieta przechowuje ten adres RAM i w ten sposób możesz znaleźć ten adres.
Po nauczeniu się ASM zdasz sobie sprawę, że ten adres wskazuje na instrukcję w .text
sekcji pliku wykonywalnego. .text
Sekcja jest ten, który posiada (binarnej) kod programu, który ma być wykonany.
Możesz to sprawdzić za pomocą:
objdump -x a.out
Jak opisano w GCC , możesz użyć tego do zainicjowania tablicy skoków. Niektóre generatory skanerów, takie jak re2c (patrz -g
parametr), używają tego do generowania bardziej kompaktowych skanerów. Może jest nawet generator parsera wykorzystujący tę samą technikę.