x87 머신 코드, 11 바이트
D9 EB
DA 31
D9 F2
DD D8
DA 09
C3
위의 바이트 코드는 apothem이 1 인 일반 n-gon의 면적을 계산하는 함수를 정의합니다. x87 FPU 명령어 (x86 프로세서의 클래식 부동 소수점 단위)를 사용하여이 계산을 수행합니다.
표준 x86 레지스터 기반 호출 규칙 (이 경우 __fastcall
)에 따라 함수의 인수는 ECX
레지스터에 전달 된 정수에 대한 포인터 입니다. 함수의 결과는 부동 소수점 값이며 x87 부동 소수점 스택 (register ST0
) 의 맨 위에 반환됩니다 .
온라인으로 사용해보십시오!
ungolfed 어셈블리 니모닉 :
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
여기서 사용하는 것처럼 간단 합니다. 우리는 또한 multiply-and-pop을 수행 할 수 있습니다 .1.0을 곱해 도 결과가 변경되지는 않지만 2 바이트 (코드 크기에서 이기지 않음)이며 더 느리게 실행되며 불필요한 불확실성을 초래할 수 있습니다 결과.
최신 프로그래머 나 컴파일러는 에이징 x87 대신 SSE (및 이후) 명령어 세트를 사용하지만 새로운 ISA에서는 탄젠트를 계산하는 단일 명령어가 없기 때문에 구현하는 데 더 많은 코드가 필요합니다.
Area@RegularPolygon
이어야한다Area@*RegularPolygon
; 지금은 변수에서 캡처 할 수 없습니다. 즉,f = Area@RegularPolygon; f[3]
작동하지 않습니다. 관련 메타 토론