x87マシンコード、11バイト
D9 EB
DA 31
D9 F2
DD D8
DA 09
C3
上記のコードバイトは、アポセム1の通常のnゴンの面積を計算する関数を定義します。x87FPU 命令(x86プロセッサの古典的な浮動小数点ユニット)を使用してこの計算を行います。
標準のx86レジスタベースの呼び出し規約(この場合は__fastcall
)に従って、関数の引数はECX
レジスタに渡される整数へのポインタです。関数の結果は、x87浮動小数点スタック(レジスターST0
)の最上部に返される浮動小数点値です。
オンラインでお試しください!
非ゴルフアセンブリニーモニック:
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
ご覧のとおり、これは基本的に、指定された式の単純な計算
結果です。result= n * tan(π/ n)
興味深い点がいくつかあります。
- x87 FPUには、定数値PI(
FLDPI
)をロードするための専用命令があります。これはめったに使用されませんでした(当時は明らかにそうではありませんでした)が、バイナリに定数を埋め込みロードするよりもサイズが短くなっています。
- 計算接線のx87 FPU命令は
FPTAN
、結果入力レジスタ(FPUスタックの最上位)の値を置き換え、しかしまた、 FPUスタックの最上部に一定1.0を押します。これは8087との後方互換性のために行われます(これが8087で行われた理由がわかりません。おそらくバグです)。つまり、この不要な値をスタックからポップする必要があります。FSTP st0
ここで使用するように、これを行うための最速かつ最短の方法はシンプルです。1.0を乗算しても結果は変わらないため、multiply-and-popを実行することもできますが、これは2バイトであるため(コードサイズが増加しないため)、実行速度が遅くなり、不必要な不確定性が生じる可能性があります結果。
最新のプログラマーまたはコンパイラーは、古くなったx87ではなく、SSE(およびそれ以降)の命令セットを使用しますが、これらの新しいISAでタンジェントを計算する単一の命令はないため、実装するためにより多くのコードが必要になります。
Area@RegularPolygon
する必要がありArea@*RegularPolygon
ます; 現在のように、変数にキャプチャすることはできません。つまり、f = Area@RegularPolygon; f[3]
機能しません。関連するメタディスカッション