Czytałem, że jeśli bit eflags 18 (AC-wyrównanie wyboru) może być modyfikowany, wiesz CPU jest 486 lub nowszy. W 386 bit jest odporny na modyfikacje.Jak działa bit eflags bit 18 (kontrola wyrównania) x86? (Odnośnie sprawdzania dla 386 vs. 486 i późniejszych).
ja podnoszone następujące kod montażowe z this site i dodano uwagi wyczerpujące (pozostawiając nienaruszone składni nieparzyste):
asm
mov bx,sx ; Save the stack pointer to bx (is sx a typo or a real register?).
and sp,$fffc ; Truncate the stack pointer to a 4-byte boundary.
pushfl ; Push the eflags register to the stack.
pop eax ; Pop it into eax.
mov ecx,eax ; Save the original eflags value into ecx.
xor eax,$40000 ; Flip bit 18 in eax.
push eax ; Push eax to the stack.
popfl ; Pop modified value into eflags.
pushfl ; Push eflags back onto the stack.
pop eax ; Pop it into eax.
xor eax,ecx ; Get changed bits from the original value.
setz al ; Set al register to 1 if no bits changed (0 otherwise).
and sp,$fffc ; Truncate the stack pointer to a 4-byte boundary.
push ecx ; Push ecx (original eflags) to stack.
popfl ; Pop it into eflags to restore the original value.
mov sp,bx ; Restore the original stack pointer.
end ['eax','ebx','ecx'];
CPU 386 to czy rejestr wsp jest ustawiony na 1, na końcu (zakładając od samego początku, że nie jest starsza), a jest 486 lub nowsza w przeciwnym razie. Rozumiem tę część.
Czego nie rozumiem, dlaczego wskaźnik stosu musi zostać obcięty do granicy 4-bajtowej przed wykonaniem testu modyfikacji flagi? Zakładam, że ma on ustawić bit 18, ponieważ jest to bit wyrównania, mimo wszystko ... ale xor z 0x40000 odwróci bit niezależnie od jego wartości. Innymi słowy, test modyfikacji powinien mieć taki sam wynik, niezależnie od wartości początkowej, prawda?
Jeśli odpowiedź brzmi "nie", moim najlepszym [niewykształconym] domysłem "dlaczego" jest: "Może następujące instrukcje push/pop mogłyby wymusić wyrównanie?" Wyrównano by niewyrównany wskaźnik stosu i spowodowało odwrócenie bitu wyrównania od 0 do 1. W takim przypadku udana modyfikacja wydaje się nieskuteczna, i na odwrót. " (EDYCJA: Jest to zdecydowanie niepoprawne, ponieważ bit dopasowania ma na celu raczej wymuszenie niż śledzenie, a ponadto wątpię, aby pop/push wymusił wyrównanie na wcześniej niewyrównanym stosie.)
Nawet jeśli tak jest, jaki jest cel wyrównania wskaźnika stosu ponownie po teście (tuż przed przywróceniem oryginalnych eflagów i wskaźnika stosu)? Czy nie powinno to już być na 4-bajtowej granicy z wcześniej? Jeśli nie, to jak to się mogło zmienić z wartości 4-bajtowych?
Krótko mówiąc, niektóre instrukcje wydają mi się zbędne i wydaje mi się, że brakuje mi czegoś ważnego. Czy ktoś może to wyjaśnić?
(Pytanie boczne: Pierwsza linia kopiuje wartość z "sx" do bx. Nigdy nie widziałem odniesienia do rejestru sx w dowolnym miejscu.To rzeczywiście istnieje, czy jest to literówka? klucz jest dość daleko od klawisza "p", przynajmniej na klawiaturach amerykańskich.)
EDYCJA: Teraz, kiedy to pytanie zostało odebrane, postanowiłem usunąć niepoprawny komentarz z dwóch linii linii w kodzie. Początkowo założyłem, że wyrównanie stosu ustawi bit dopasowania, i napisałem to do mojego komentarza (reszta pytania jest kontynuowana z tą niepoprawną logiką). Zamiast tego bit sprawdzania wyrównania naprawdę polega na wymuszaniu wyrównania (a nie na śledzeniu go), jak wskazuje flolo na odpowiedź dotyczącą sigbusa. Postanowiłem poprawić komentarze, aby uniknąć zamieszania osób z podobnymi pytaniami.
Jakie muzeum włamałeś się, aby znaleźć 386? Lepiej odłóż to z powrotem. –
LOL! Nigdy nie dotknąłem pulpitu 386, o ile wiem ... Znowu zszedłem ze starym 286, ale od razu przeskoczyłem do Pentium 75. Postanowiłem po prostu zakryć moje bazy przed wywołaniem instrukcji CPUID (najpierw upewnij się, że nie masz 386, a następnie przetestuj 21 bitów eflags na obecność CPUID), w sytuacji, gdy jakiś szalony kiedykolwiek zdecydował się użyć mojego kodu na antycznym sprzęcie. Chyba jestem po prostu analna, ale przynajmniej nie sprawdzam 8-bitowych i 16-bitowych procesorów, ponieważ nowoczesne kompilatory najwyraźniej nawet nie generują kodu. ;) –