Asembler 80x86 - użycie XOR zamiast SUB

0

Witam,

Czy jest jakaś różnica w użyciu instrukcji sub i xor w następującym zadaniu:

W rejestrze AX mamy stałą wartość 1111 1111 1111 1111.
W rejestrze BX mamy downolą wartość.

Chcę wykonać operację odejmowania AX - BX.

Czy jest zatem różnica w sub ax, bx i xor ax, bx.

Wynik będzie (chyba) taki sam, a o użycie prosiłaby się (ze względu na operację, którą trzeba wykonać) instrukcja sub, natomiast w pewnej książce o asemblerze autor użył właśnie instrukcji xor, nie uzasadniając tego.

0

Na pojedyńczym bicie
1 xor a = not(a)
1 sub a = not(a)

Tak więc w przypadku gdy rejestr jest wypełniony jedynkami to te same operacje.

0

Pytanie było czemu zrobił tak a nie inaczej ;P
Ktoś musiałby rzucić okiem na szybkość tych dwóch operacji i na sposób w jaki działają, bo możliwe że w takim przypadku xor jest po prostu szybszy. Ale możliwe też że nie jest, a autor sobie tak po prostu napisał, żeby pokazać że można :P

0

Źle zrozumiałem pytanie.
xor jest szybszy od sub. W czasach 8086 do zerowania rejestru zamiast mov używało się właśnie xora.
Na prockach powyżej 80386 pewnie to nie ma znaczenia.

0

To że autor tak napisał to są jego widzimisie, różnicy znacznej nie ma ;-)

rnd napisał(a)

xor jest szybszy od sub. W czasach 8086 do zerowania rejestru zamiast mov używało się właśnie xora.
Na prockach powyżej 80386 pewnie to nie ma znaczenia.

Xor'a do zerowania raczej, nie używało się z powodu szybkości.
Tylko, że zakodowana instrukcja xor rejestr, rejestr zajmowała mniej bitów niż mov rejestr, 0

0
rnd napisał(a)

xor jest szybszy od sub.
Nie.

rnd napisał(a)

W czasach 8086 do zerowania rejestru zamiast mov używało się właśnie xora.
Na prockach powyżej 80386 pewnie to nie ma znaczenia.
I używa się do dziś, bo ma znaczenie. xor to dwa bajty, mov to pięć => można więcej kodu upchać w jednej linii cache.

0
Fanael napisał(a)
rnd napisał(a)

xor jest szybszy od sub.
Nie.

Ostatnio widziałem jakiś benczmark, i wyszło że rzeczywiście xor jest (niewiele) szybszy od suba, a testowane było na bodajże Core 2. Za to mov "powinien" być wolniejszy - dużo dłuższa instrukcja.

Fanael napisał(a)
rnd napisał(a)

W czasach 8086 do zerowania rejestru zamiast mov używało się właśnie xora.
Na prockach powyżej 80386 pewnie to nie ma znaczenia.
I używa się do dziś, bo ma znaczenie. xor to dwa bajty, mov to pięć => można więcej kodu upchać w jednej linii cache.

Nawet optymalizujące kompilatory stosują instrukcję xor dla operacji typu "int i=0".

0

To zależy - w pewnych sytuacjach szybszy jest xor, w innych sub... Nie dam głowy, bo nie mam manuali pod ręką, ale coś mi się wydaje, że xor i sub są tak samo szybkie w general case...

0

Przy współczesnych architekturach? Wpływ pamięci cache, dekodera instrukcji (było nie było, Intelowski zestaw do małych nie należy), 'przewidywania' przepływu... Benchmarki to raczej próba poparcia swojej tezy ;)

0

ze co?
xor to zupelnie co innego niz sub.

zapomniales ze sub odsluguje carry, czyli zamienia 0 na 1 w gore dopoki nie zamieni 1 na 0.

add odwrotnie.

xor tylko zamienia bity bez przenoszenia.

0
Fanael napisał(a)

xor to dwa bajty, mov to pięć => można więcej kodu upchać w jednej linii cache.

Skąd brać takie informacje, ile bajtów zajmuje konkretny rozkaz?

0

Przede wszystkim z dokumentacji procesorów. (tak mi się wydaje ;) )

Albo chociażby
Instrukcje procesorów rodziny 80x86 (A)

0
lol54 napisał(a)

ze co?
xor to zupelnie co innego niz sub.

Że to, że oba nadają się do zerowania:

  xor eax,eax
  sub ebx,ebx
  mov ecx,0

Wszystkie trzy instrukcje zapisują zero do rejestru. Z czego niestety mov zajmuje najwięcej bajtów (pięć?) i będzie wolniejszy.
Różnice mogą być we flagach.

aloesss napisał(a)

Skąd brać takie informacje, ile bajtów zajmuje konkretny rozkaz?

Utworzyć plik

      USE32       ; albo use16, use64
      xxx         ; nasza instrukcja

I skompilować go NASMem.

0

Na w miarę nowych procesorach xor i sub wykonują się tak samo szybko i zajmują tyle samo, tak samo szybko się dekodują, więc różnice mogą być co najwyżej w granicach błędu pomiarowego.

Kunai:
Trudność dekodowania instrukcji nie zależy od tego ile ich jest lub jak są skonstruowane, ale od tego czy da się sensownym kosztem zdekodować kilka instrukcji naraz. Instrukcje u Intela mogą mieć od 1 bajta do chyba kilkunastu, nie ma żadnych informacji jakie długie będą kolejne instrukcje, nie ma żadnych znaczników typu "to jest instrukcja" / "to jest kontynuacja instrukcji", więc najbardziej skomplikowanym modułem w prockach x86 jest chyba dekoder instrukcji.

0

Instrukcje u Intela mogą mieć od 1 bajta do chyba kilkunastu, nie ma żadnych informacji jakie długie będą kolejne instrukcje, nie ma żadnych znaczników typu "to jest instrukcja" / "to jest kontynuacja instrukcji", więc najbardziej skomplikowanym modułem w prockach x86 jest chyba dekoder instrukcji

Twoja znajomość sprzętu jest powalająca.

0
donkey7 napisał(a)

Kunai:
Trudność dekodowania instrukcji nie zależy od tego ile ich jest lub jak są skonstruowane, ale od tego czy da się sensownym kosztem zdekodować kilka instrukcji naraz. Instrukcje u Intela mogą mieć od 1 bajta do chyba kilkunastu, nie ma żadnych informacji jakie długie będą kolejne instrukcje, nie ma żadnych znaczników typu "to jest instrukcja" / "to jest kontynuacja instrukcji", więc najbardziej skomplikowanym modułem w prockach x86 jest chyba dekoder instrukcji.

Wystarczy, że instrukcje rozpisane są 'na drzewie', nie ma potrzeby jawnego rozdzielania ich. Co do dekodowania kilku naraz, nie wiem czy tak to działa, nigdy o tym nie czytałem.

Mam natomiast wrażenie, że trochę to jednak zależy od instrukcji. Tzn. jak wiadomo instrukcje tłumaczone są na mikroinstrukcje - takiego xor z pewnością łatwiej jest zdekodować, niż którąś z dziwacznych instrukcji SSE4... albo przyszłego AES-a. Może to po prostu copy-paste z jakiejś predefiniowanej tablicy szablonów, ale wydaje mi się, że potrzeba tu nieco więcej logiki ;)

Poza tym, gdyby instrukcji było mniej, dałoby się je zakodować na mniejszej liczbie bitów.

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