deniz.in

Piyasalar

Hava durumu

Hava durumu yükleniyor

· kaynak Hacker News – Front Page (hnrss.org)

8087'yi tersine mühendislikle çözümlemek: FSCALE'ın ardındaki 140'tan fazla micro-instruction

Righto.com'daki bir söküm incelemesi, 8087'nin FSCALE talimatını 140'tan fazla micro-instruction boyunca izliyor ve bugünün floating-point standardını belirleyen coprocessor'ün özel durumları nasıl ele aldığını gösteriyor.

8087'yi tersine mühendislikle çözümlemek: FSCALE'ın ardındaki 140'tan fazla micro-instruction

Tek talimat, 140'tan fazla micro-adım

Hacker News ana sayfasına ulaşan righto.com'daki bir tersine mühendislik yazısı, Intel'in 1980 tarihli floating-point coprocessor'ü 8087'deki tek bir talimatın — FSCALE'ın — ardındaki microcode'u inceliyor. Yazar, çipin iç kontrol kodunu çözen Opcode Collective adlı bir grubun parçası ve projeye FSCALE'ın açıklamasının neredeyse kolay olacağını bekleyerek girdi. Yazıya göre öyle değil: talimat 140'tan fazla micro-instruction ve üç iç içe subroutine çağrısı seviyesi tüketiyor ve analiz ayrıca çipin gizli bir özelliğini ortaya çıkarıyor.

Uyumsuz aritmetikten fiili standarda

Bağlam olarak, yazı 8087'nin temizlediği kaosu özetliyor: 1970'ler boyunca floating-point aritmetiği kabaca bir düzine birbiriyle uyumsuz uygulamaya bölünmüştü; çoğu matematiği doğru kılmak yerine donanımı kolaylaştıracak biçimde tasarlanmıştı ve sayısal kararsızlık yinelenen bir sonuçtu. Intel, 8087'yi 1980'de piyasaya sürdü ve onu en çetrefil köşe durumlarda bile en yüksek doğruluğu verecek şekilde mühendislik etti. Bir IBM PC'ye takıldığında, tablolama programlarından CAD'e kadar çeşitli yazılımlarda floating-point işlemleri 100 kata kadar hızlandırabiliyordu. Yazının belirttiğine göre daha kalıcı etkisi şu: çipin davranışı, bugünün bilgisayarlarının çoğunun izlediği floating-point kurallarına dönüştü.

Çipi mikroskop altında okumak

Microcode'u kurtarmak, bir 8087 paketini açmayı ve 5'e 6 milimetrelik çipi yüksek çözünürlükte fotoğraflamayı gerektirdi. Yazının anlattığına göre microcode ROM'u çipin merkezinde yer alıyor ve 1.648 micro-instruction saklıyor. Solunda, bu talimatları sıralayan ve jump'larla subroutine çağrılarını yöneten microcode motoru bulunuyor. Çipin alt yarısı ise datapath — yani aritmetik devresi — exponent'leri işleyen 16-bitlik bir yol ile significand'ları işleyen 64-bitlik bir yola bölünmüş durumda.

FSCALE'ın üzerinde çalıştığı mekanizma

Talimatın kod yolu birkaç fonksiyonel bloğa dokunuyor. Bir exponent ROM'u sabitleri tutarken, adanmış bir exponent dönüştürücüsü exponent alanlarını denetliyor, özel değerleri tanıyor ve exponent gösterimleri arasında çeviri yapıyor. Büyük bir shifter, 64-bitlik bir değeri istenen sayıda konum sola veya sağa kaydırabiliyor. Toplayıcı (adder), çipteki gerçek aritmetiğin gerçekleştiği yer — microcode, çarpma, bölme ve karekök gerçekleştirmek için onu bir döngüde çalıştırıyor — B register'ı girişlerden birini beslerken bir toplam register'ı çıktıyı yakalıyor. Sayılar sekiz stack register'ında ya da geçici depolamada yaşar: tmpA ve tmpB 80 bit genişliğinde ve her birinin iki tag biti vardır; tmpC ise yalnızca 64 bitlik bir significand tutar.

Asıl iş köşe durumlarda

FSCALE bir değeri iki'nin bir kuvvetiyle ölçekler — olağan durumda exponent'e küçük bir dokunuş, hız açısından gerçek bir çarpmayı geçmesinin nedeni de bu. Kalan yüzden fazla micro-instruction ise geri kalan her şeyi ele almak için var.

Programcının görebildiği sekiz register'ın her biri stack biçiminde örgütlenmiş, 80 bit genişliğinde ve içeriklerini geçerli, özel, sıfır ya da boş olarak işaretleyen — programcılardan büyük ölçüde gizli — bir tag taşır; sonsuz, NaN ve denormalize değerlerin tümü özel sayılır. Bir program ister daha dar float'lar, ister tamsayılar, ister binary-coded decimal saklasın, her şey içeride 80 bitlik bir "temporary real" olarak tutulur: bir işaret biti, 16383 bias'ıyla saklanan 15 bitlik bir exponent (gerçek aralık yaklaşık -16382 ile 16383 arası) ve 64 bitlik bir significand.

Bunun üstüne altı exception türü binilir: geçersiz işlem, overflow, underflow, sıfırla bölme, denormalize operand ve hassasiyet (precision). Kontrol register'ındaki bitler, her exception için maskelenip maskelenmediğine karar verir. Maskelenmemiş bir exception, yazılımın yanıt verebilmesi için host 8086'yı kesintiye uğratır; maskelenmiş olan ise coprocessor'ün hesaplamayı sürdürmesine ve verebileceği en doğru yanıtı üretmesine izin verir: geçersiz sonuçlar için NaN, overflow ya da sıfırla bölme için sonsuz, tam olmayan sonuçlar için ise yuvarlama ikame edilir. Yazının açıkladığı gibi, microcode'u şişiren tam da bu esnekliktir: özel operand'ların ve exception ayarlarının her birleşimi, rutin içinde kendi yoluna gereksinim duyar.

Neden önemli

8087'nin kuralları, modern donanımın çoğunun miras aldığı floating-point davranışına dönüştü; dolayısıyla microcode'unu belgelemek, o semantiğin fiziksel olarak nereden geldiğini belgelemektir. FSCALE incelemesi, köşe durumlarda doğruluk bir tasarım hedefi olduğunda "basit" bir talimatın ne kadar görünmez mekanizma gerektirdiğini gösteriyor; sergilenen maskeli exception yaklaşımı — hesaplamayı sürdür ve mümkün olan en iyi yanıtı döndür — yazılımın hâlâ birlikte yaşadığı bilinçli bir 1980 kararıdır. Emülatör yazarları, CPU tarihçileri ve bir floating-point biriminin 30 milimetre kare silikona nasıl sığdığını merak eden herkes için Opcode Collective'in çalışması, 8087'yi bir kara kutudan okunabilir koda dönüştürüyor.

  • #intel
  • #microcode
  • #reverse-engineering
  • #floating-point
  • #retro-computing

İlgili yazılar