Asembler, zapis bajtów oraz słów i ich wartości

0

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 ?

0

Zapraszam do lektury :)

http://en.wikipedia.org/wiki/Endianness

Jak chcesz szukać sam to: Little Endian i Big Endian.

0

@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.

0
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 ;)

0

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.

0

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.

1 użytkowników online, w tym zalogowanych: 0, gości: 1