2012-11-17 9 views
12

Dlaczego instrukcje x86 INC (przyrost) i DEC (dekrementacja) nie wpływają na CF (flaga przenoszenia) w języku FLAGSREGISTER?dlaczego instrukcje INC i DEC nie mają wpływu na flagę carry?

+1

@AndreasBrinck To pytanie nie dotyczy "dlaczego?", Ani odpowiedzi na nie nie odpowiadają na pytanie o wybór projektu. –

+4

NIE JEST TO DOKŁADNA DUPLIKACJA. Drugie pytanie pyta, jak * użyć * INC/DEC i po prostu zauważa, że ​​przeniesienie nie jest aktualizowane. To pytanie zadaje pytanie * dlaczego * nie jest aktualizowane. Uważam, że kilka osób chce zamknąć pytanie jako dokładny duplikat, gdy nie jest, co oznacza, że ​​"moderatorzy" przeskakują broń. To nie jest pomocne IMHO dla SO. –

Odpowiedz

23

Aby zrozumieć, dlaczego prawdopodobnie trzeba pamiętać, że obecne procesory "x86" z wartościami 32- i 64-bitowymi uruchomiły życie o wiele bardziej ograniczone maszyny 8-bitowe, wracając do Intel 8008. (Kodowałem w tym świecie z powrotem w 1973, wciąż pamiętam (ugh) to!).

W tym świecie rejestry były cenne i małe. Potrzebujesz inc/dec do różnych celów, najczęstszego kontrolowania pętli bycia. Wiele pętli obejmowało wykonywanie "arytmetyki wieloprecyzyjnej" (na przykład 16 bitów lub więcej!) Dzięki ustawieniu bitu Z na wartość inc/dec, można je dość dobrze kontrolować w pętli; przez naleganie, że instrukcje sterowania pętlą nie zmieniają bitu przenoszenia, przenoszenie jest zachowywane w iteracjach pętli i można zaimplementować operacje wielocy- cyzacji bez zapisywania ton kodu, aby zapamiętać stan przenoszenia.

To zadziałało całkiem dobrze, kiedy przyzwyczaiłeś się do brzydkiego zestawu instrukcji.

Na bardziej nowoczesnych maszynach z większymi rozmiarami słów, nie potrzebujesz tego, więc INC i DEC mogą być semantycznie równoważne ADD ..., 1 itd. W rzeczywistości to jest to, czego używam, kiedy potrzebuję zestaw noży: -}

Głównie trzymam się z daleka od INC i DEC teraz, ponieważ wykonują częściowe aktualizacje kodu warunku, co może powodować zabawne przeciągnięcia w rurociągu, a ADD/SUB nie. Więc tam, gdzie to nie ma znaczenia (większość miejsc), używam ADD/SUB, aby uniknąć straganów. Używam INC/DEC tylko wtedy, gdy zachowanie kodu ma małe znaczenie, np. Dopasowanie do linii podręcznej, w której rozmiar jednej lub dwóch instrukcji sprawia, że ​​różnica ma znaczenie. To chyba bez sensu nano [dosłownie!] - optymalizacja, ale w moich kodeksowych zwyczajach jestem dość stara.

Moje wyjaśnienie mówi nam, dlaczego INC/DEC ustawił bit zero. Nie mam szczególnie szczegółowego wyjaśnienia, dlaczego INC/DEC ustawił znak (i ​​bity parzystości).

EDYCJA Kwiecień 2016: Wygląda na to, że problem z przeciągnięciem jest lepiej obsługiwany na nowoczesnych komputerach x86. Zobacz INC instruction vs ADD 1: Does it matter?

0

Ponieważ nie ma potrzeby, aby wpływać. Wystarczy sprawdzić flagę Zero. Tak więc, po instrukcji inc i dec flaga carry pozostaje taka sama iw niektórych przypadkach jest to przydatne.

4

Pytanie, dlaczego znak gdy masz zerowy flagi ustawione przez INC/DEC najlepiej skierowana z pytaniem: wolisz zrobić bez opcji ?

a) for (n=7;n>=0;n--) // translates to `dec + jns` 
b) for (n=8;n>0;n--) // translates to `dec + jnz` 

Jak Ira Baxter już wyjaśnione, Carry flagi jest używana w wielu algorytmów - to nie tylko multiprecision arytmetyki, ale również dla powiedzmy obróbki bitmap monochromatycznych/CGA/EGA era: ten przesuwa 80 pikseli szeroki jeden wiersz piksel w prawo ...

 mov cx, 10 
begin: lodsb 
     rcr al,1 // this is rotate though carry: 
     stosb  // for the algorithm to work, carry must not be destroyed 
     LOOP begin // 

Ale potem: dlaczego parytet?

Uważam, że odpowiedź brzmi: dlaczego nie. Ten zestaw instrukcji pochodzi z końca lat 70-tych, kiedy tranzystory były rzadkością. Odmowa obliczenia flagi parzystości dla pewnej szczególnej instrukcji nie miałaby sensu, ale tylko dodana do złożoności procesora.