x87 Makine Kodu, 11 bayt
D9 EB
DA 31
D9 F2
DD D8
DA 09
C3
Yukarıdaki kod baytları, normal bir n-gon alanını 1 apothem ile hesaplayan bir işlevi tanımlar . Bu hesaplamayı yapmak için x87 FPU komutlarını (x86 işlemcilerdeki klasik kayan nokta birimi) kullanır.
Standart x86 kayıt tabanlı bir arama kuralını (bu durumda __fastcall
) izleyen işlevin argümanı, ECX
kayıtta iletilen tamsayıya bir göstericidir . İşlevin sonucu, x87 kayan nokta yığınının (kayıt ST0
) en üstünde döndürülen bir kayan nokta değeridir .
Çevrimiçi deneyin!
Ungolfed montaj anımsatıcıları:
D9 EB fldpi ; load constant PI at top of FPU stack
DA 31 fidiv DWORD PTR [ecx] ; divide PI by integer input (loaded from pointer
; in ECX), leaving result at top of FPU stack
D9 F2 fptan ; compute tangent of value at top of FPU stack
DD D8 fstp st0 ; pop junk value (FPTAN pushes 1.0 onto stack)
DA 09 fimul DWORD PTR [ecx] ; multiply by integer input (again, loaded via ECX)
C3 ret ; return control to caller
Gördüğünüz gibi, bu sadece verilen formülün basit bir hesaplamasıdır,
sonuç = n * tan (π / n)
Sadece birkaç ilginç şey işaret ediyor:
- X87 FPU, PI (
FLDPI
) sabit değerini yüklemek için özel bir talimat içerir . Bu gün içinde bile nadiren kullanıldı (ve açıkçası şimdi çok daha az), ancak boyut, bir sabitin ikili dosyaya gömülmesinden ve yüklenmesinden daha kısa.
- Teğet hesaplamak için x87 FPU komutu
FPTAN
, giriş yazmacının (FPU yığınının üst kısmı) değerini sonuçla değiştirir, ancak aynı zamanda FPU yığınının üstüne sabit 1.0'ı iter. Bu 8087 ile geriye dönük uyumluluk için yapılır (bunun neden 8087'de yapıldığı hakkında hiçbir fikrim yok; muhtemelen bir hata). Bu, gereksiz bu değeri yığının dışına çıkarmamız gerektiği anlamına gelir. Bunu yapmanın en hızlı ve en kısa yolu FSTP st0
, burada kullandığımız gibi basit . Ayrıca, çarpma-ve-pop da yapabilirdik , çünkü 1.0 ile çarpmak sonucu değiştirmez, ancak bu da 2 bayttır (bu nedenle kod boyutunda kazanç olmaz), muhtemelen daha yavaş yürütülür ve gereksiz belirsizlik getirebilir sonuç.
Modern bir programcı veya derleyici, yaşlanma x87 yerine SSE (ve üstü) komut setini kullansa da, bu yeni ISA'larda bir teğet hesaplamak için tek bir talimat olmadığından, bunun uygulanması için daha fazla kod gerekir.
Area@RegularPolygon
olmalıArea@*RegularPolygon
; şimdi olduğu gibi, bir değişkende yakalanamaz. Yani,f = Area@RegularPolygon; f[3]
çalışmıyor. Alakalı meta tartışma