Spędzam trochę czasu na programowaniu zespołów (w szczególności gazu), a ostatnio dowiedziałem się o dyrektywie wyrównania. Myślę, że zrozumiałem podstawy, ale chciałbym głębiej zrozumieć jego naturę i kiedy stosować wyrównanie.Kiedy w montażu powinny być stosowane wyraźne dyrektywy wyrównania?
Na przykład, zastanawiałem się nad kodem zestawu prostej instrukcji zmiany C++. Wiem, że w pewnych okolicznościach switch oparte są na stołach skakać, jak w następnych kilku linii kodu:
.section .rodata
.align 4
.align 4
.L8:
.long .L2
.long .L3
.long .L4
.long .L5
...
.align 4 wyrównuje następujące dane na następnej granicy 4 bajtów, która zapewnia, że ściągam te miejsca pamięci lokalizacje są wydajne, prawda? Myślę, że dzieje się tak, ponieważ przed zmianą instrukcji mogły pojawić się pewne rzeczy, które spowodowały niewspółosiowość. Ale dlaczego są dwa połączenia z .align? Czy są jakieś reguły dotyczące wywoływania .align, czy powinno się to robić po każdorazowym zapisaniu nowego bloku danych w pamięci, a coś wcześniej mogło spowodować niewspółosiowość?
W przypadku tablic wygląda na to, że wyrównanie odbywa się na granicach 32-bajtowych, gdy tylko macierz zajmuje co najmniej 32 bajty. Czy jest to skuteczniejsze, aby zrobić to w ten sposób, czy też istnieje inny powód 32-bajtowej granicy?
Byłbym wdzięczny za wszelkie wyjaśnienia lub wskazówki dotyczące literatury.
Moje opanowanie języka asemblerowego jest ograniczone do 6510, które nie zawierało instrukcji wyrównania. Ale w oparciu o moją wiedzę na temat wyrównania pamięci w ustawieniach C++, domyślam się, że instrukcja "wyrównania" nie jest faktyczną instrukcją procesora. Może to być po prostu dyrektywa asemblera, wskazująca gdzie wstawić następne kody opcodujące. Jeśli tak, dwie równoległe dyrektywy z rzędu są takie same, jak napotkanie tylko jednego. –
Myślałem, że '.align 2' wyrównuje kod do 2^2 = 4 bajtów. W twoim przypadku, w którym masz '.align 4', wyrównanie jest na 2^4 = 16 bajtów. – 71GA