Jestem trochę zdezorientowany między poziomem mikroprogramowania a poziomem języka maszynowego. Na przykład:
- Gdzie znajdują się oba typy programów podczas ich wykonywania?
- Czy masz instrukcje mapowania 1: 1 do prawdziwej instrukcji języka asemblera?
- Czy format jest zdefiniowany w architekturze procesora?
Odpowiedzi:
Mikrokod to kolejny poziom abstrakcji poza kodem maszynowym. Rzeczywisty procesor korzysta z mikrokodu, a silnik translacji konwertuje kod maszynowy na mikrokod w locie. Odbywa się to z różnych powodów, w tym z szybszych, mniejszych procesorów, łatwiejszych do stworzenia złożonego procesora z mniejszą liczbą debugowania i dla kompatybilności wstecznej. Na przykład zestaw instrukcji x86 zawiera niektóre instrukcje przetwarzania ciągu, które są rzadko używane. Jednak, aby zachować zgodność wsteczną, muszą być nadal dostępne w nowoczesnych procesorach x86. Zamiast podłączać ścieżkę wykonania tych instrukcji, są one konwertowane na mikrokod i wykonywane. Oszczędza to krzem, a jednocześnie pozostaje kompatybilny wstecz.
Kod maszynowy znajduje się w pamięci podręcznej (po wyciągnięciu z pamięci RAM). Mikrokod znajduje się w pamięci podręcznej mikrokodu, w zależności od konkretnej architektury komputera. Pamięć podręczna może być wystarczająco duża, aby pomieścić wystarczającą ilość mikrokodu, aby pomieścić przekonwertowany mikrokod z największej możliwej instrukcji kodu maszynowego, lub może być większą pamięcią podręczną, która przechowuje przekonwertowane wyniki wielu kodów maszynowych, aby nie trzeba było konwertować wszystkich kod maszynowy na każdej iteracji dla małych pętli.
W niektórych architekturach konwertowany mikrokod nie jest nigdzie przechowywany - jednostka pobierania / tłumaczenia po prostu wyrzuca serię instrukcji mikrokodu opartych na aktualnie wykonywanym kodzie maszynowym. W tym przypadku mikrokod wykonuje się z jakiegoś ROM-u, a kod maszynowy jest w zasadzie indeksem do ROM-u, wskazując na szereg instrukcji mikrokodu, które należy uruchomić, aby w pełni wykonać instrukcję kodu maszynowego.
Kod maszynowy i kod asemblera ogólnie są odwzorowane w stosunku 1: 1 do instrukcji asemblacji. To zależy od asemblera. Asemblery wysokiego poziomu mogą mieć duży zestaw makr, które pozwalają napisać jedną linię kodu asemblera, a asembler wygeneruje kilka kodów maszynowych.
Ale ogólnie „czysty” język asemblera można przekształcić bezpośrednio w kod maszynowy, korzystając z tabeli zestawów instrukcji w podręczniku procesora.
Nie jestem jednak pewien, co rozumiesz przez „instrukcje prawdziwej operacji”. Być może możesz wyjaśnić odniesienie.
Format zarówno kodu maszynowego, jak i mikrokodu są określone przez architekturę procesora.
źródło
Zasadniczo mikrokod rozszerza zestaw instrukcji ograniczonego procesora, aby zawierał instrukcje wyższego poziomu, które byłyby kłopotliwe w implementacji sprzętowej, ale stosunkowo łatwe do zbudowania przy użyciu istniejących instrukcji. Mikrokod pozwala procesorowi z małym zestawem instrukcji działać jak ten z większym zestawem instrukcji.
Powiedzmy, że pracujesz z zestawem instrukcji MARIE i chciałbyś funkcji Add x, y, ale architektura zezwala tylko na Add x (która dodaje to, co aktualnie jest w rejestrze do x), więc dodajesz instrukcję mikrokodu:
Teraz, gdy kod języka maszynowego mówi:
wyszukuje funkcję DODAJ dodaną do ROM (twojego mikrokodu) i wykonuje ją. Jest to świetne, ponieważ zwiększa zestaw instrukcji, co pozwala na bardziej czytelny kod maszynowy, a ponieważ mikrokod jest przechowywany w pamięci ROM, jest również nieco szybszy niż wywoływanie LOAD i ADD z pamięci RAM.
Pracowałem w firmie, która faktycznie napisała mikrokod, aby wykonywać niestandardowe pomiary przy bardzo dużych prędkościach na swoich starszych systemach. Jednak wraz z postępami w układach FPGA przeszły one na te, które są znacznie szybsze (ponieważ faktycznie wdrażasz „instrukcje niestandardowe” w sprzęcie zamiast w pamięci ROM).
źródło
Wiele procesorów jest sterowanych przez maszynę stanu, na której sekwencję przejścia wpływ mają wykonywane instrukcje. „Instrukcje” mikrokodu często określają interakcje między różnymi rejestrami i magistralami w sposób, który nie byłby widoczny dla programisty.
Na przykład instrukcja mikrokodu dla 8-bitowego procesora w stanie nr 1 może określać, że włączanie wyjścia dla obu połówek licznika programu powinno być aktywne (powodując, że licznik programu będzie wyprowadzany na górnej i dolnej wewnętrznej szynie adresowej), sygnał licznika programu powinien być aktywny, sygnały zatrzasku adresu zewnętrznego powinny być aktywne (aby zewnętrzna szyna adresu śledziła wewnętrzny), a sygnał odczytu pamięci RAM powinien być aktywny, a sterownik powinien przejść do stanu # 2.
W stanie # 2 zewnętrzna magistrala danych powinna być zasilana do wewnętrznej pierwotnej magistrali danych, a rejestr instrukcji, który czyta z tej magistrali, powinien zostać załadowany. Licznik programu powinien, jak poprzednio, zostać wyprowadzony na obie połówki magistrali adresowej i wydany kolejny odczyt pamięci RAM. Bity 5-7 rejestru instrukcji powinny być ładowane do bitów 0-2 kontrolera stanu, bit 3 rejestru stanu powinien być ustawiony, chyba że wszystkie bity 1-7 rejestru instrukcji są ustawione, a inne bity rejestru stanu powinno być jasne, wynik netto jest taki, że następnym stanem będzie # 7- # 15.
Zauważ, że mikrokod nie jest tak naprawdę zdefiniowany pod względem instrukcji, ale raczej pod względem kombinacji sygnałów sterujących. Sprzęt nie zostanie skonfigurowany tak, aby zezwalał na instrukcje ogólnego przeznaczenia w mikrokodzie, ale raczej ładował lub wyprowadzał różne rejestry z / do szyn, na których siedzą, lub łączył różne szyny ze sobą, i używał różnych bitów lub ich kombinacji, aby wybierz różne stany. Wiele aspektów projektu będzie podłączonych na stałe (np. Kody FE i FF mogą być specjalnie umieszczone w sprzęcie, a nie w mikrokodzie). Ideą mikrokodu nie jest uruchamianie programów, ale zamiana logiki.
źródło