Cześć,
Mam pytanie dot asemblera x86.
Gdy zapiszę w pliku coś takiego:
dw 0xabcd
i skompiluje, to po podejżeniu hexdumpem będe miał 0xabcd, ale gdy skompiluje taki kod:
db 0xab
db 0xcd
to otrzymam 0xcdab, dlaczego tak ?
Cześć,
Mam pytanie dot asemblera x86.
Gdy zapiszę w pliku coś takiego:
dw 0xabcd
i skompiluje, to po podejżeniu hexdumpem będe miał 0xabcd, ale gdy skompiluje taki kod:
db 0xab
db 0xcd
to otrzymam 0xcdab, dlaczego tak ?
Zapraszam do lektury :)
http://en.wikipedia.org/wiki/Endianness
Jak chcesz szukać sam to: Little Endian i Big Endian.
@Maciej Barszczyński tak jak pisze @Ola Nordmann jest to kwestia kolejnosci bajtów od najmniej znaczącego lub od najbardziej znaczącego. Częsty problem przy niskopoziomowej komunikacji sieciowej.
Shalom napisał(a):
@Maciej Barszczyński tak jak pisze @Ola Nordmann jest to kwestia kolejnosci bajtów od najmniej znaczącego lub od najbardziej znaczącego. Częsty problem przy niskopoziomowej komunikacji sieciowej.
Źle mnie zrozumieliście, wiem że little endian jest w x86, ale jeżeli zapiszę sobie tak w kodzie:
liczba1: dw 0xAB
liczba2: db 0xC
liczba3: db 0xD
to mój mózg nie jest w stanie pojąć zmian pozycji 0xC oraz 0xD i późniejszych odwołań do tego, przecież jest przesunięcie o 1 bajt względem siebie (do przodu i tyłu)
wiem, że kompilator to ogarnie w trakcie kompilacji i odwoła się do odpowiedniego miejsca, ale jak to jest później interpretowane przez procesor
w końcu końców procesor będzie się odwoływał do 0xC z przesunięciem o 1 do przodu, a do 0xD z przesunięciem o 1 w tył ?
idąc tym tokiem, gdy odczytam słowo odwołując się do etykiety liczba1 to pobierze mi 0xAB, a gdy słowo odwołując się do etykiety liczba2, to dostanę 0xCD, a w pliku zostanie to zapisane oddzielnie. jedna para bez zmiany, druga para zmieniona.
a więc ?
ps
strasznie namotałem, liczę na wybaczenie ;)
x86 jest little-endian więc zawsze kiedy ładujesz coś z pamięci lub zapisujesz, to kolejność bajtów jest odwracana. Zawartość pliku też jest ładowana do pamięci, a więc przy ładowaniu z pliku do rejestru kolejność bajtów też jest odwracana. Kolejność w pliku przy zrzucaniu pamięci na dysk nie jest zamieniana (bo zarówno plik jak i RAM to nie są rejestry), możesz sobie to sprawdzić wczytując bajt po bajcie i wypisując.
więc zawsze kiedy ładujesz coś z pamięci lub zapisujesz, to kolejność bajtów jest odwracana.
Bzzzt! Kolejność bajtów nie jest odwracana ani w pamięci, ani w procesorze. Kolejność bajtów jest jaka jest. Komputer nie odwraca bajtów ani przy odczycie, ani zapisie, ani w trakcie operacji arytmetycznych. Chyba że zadana operacja akurat ma na tym polegać.
To byłoby bez sensu, odwracanie bajtów w te i nazad.
To dopiero na etapie wyświetlania człowiekowi (tudzież zamiany sekwencji bajtów na stringa) następuje pewne przemieszanie, ale wynika to z takiego a nie innego sposobu zapisu cyfr arabskich (ściśle: ich szesnastkowego nadzbioru), w połączeniu z przyjętą konwencją przechowywania liczb na procesorach little-endian.
dw 0xabcd
To jest liczba czterdzieści trzy tysiące dziewięćset osiemdziesiąt jeden. Na procesorze Intela zostanie zapisana jako dwa bajty: w bajcie o niższym adresie będzie wartość 0xCD, w bajcie o wyższym adresie będzie wartość 0xAB. Jeśli sobie te dwa bajty zapiszemy na papierze w ten sposób, że z lewej napiszemy 0xCD a z prawej 0xAB, to rzeczywiście, wygląda to jakby kolejność była „zła”.
Dla komputera nie ma lewo i prawo. Jest bajt o mniejszym i bajt o większym adresie. Możemy to sobie przedstawić na rysunku jako lewo-prawo, góra-dół, tył-przód, albo odwrotnie, ale to tylko (ułomny) sposób reprezentacji.
liczba1: dw 0xAB
liczba2: db 0xC
liczba3: db 0xD
To ci wygeneruje cztery bajty, kolejno:
liczba1: db 0xAB
db 0x00
liczba2: db 0x0C
liczba3: db 0x0D
idąc tym tokiem, gdy odczytam słowo odwołując się do etykiety liczba1 to pobierze mi 0xAB,
Tak,
a gdy słowo odwołując się do etykiety liczba2, to dostanę 0xCD,
Nie,0x0D0C
. Bajt ma zawsze dwie cyfry szesnastkowe.
Oczywiście 0xC to ta sama liczba co 0x0C, 0x000C, 0x00000000000000000000000000000000C itd.