경우 인쇄 후 0.008로를 곱하고 메모리에서로드되거나 메모리에만 저장 될 수있는 스택 된 레지스터 세트를 사용했음을 기억하십시오.
Intel manual 1을 사용하거나 향수를 느낀다면 reading this 387 manual from Intel dated 05/26/1987을 사용하여 직접 FPU 프로그래밍 모델에 대해 문서화 할 수 있다고 가정합니다. 에서
st(0)
의 콘텐츠 저장 명령 fstp dword [eax]
어드레스는 eax
의해을 나타낸다. 이러한 주소 지정 모드는 간접 주소 지정 모드이며 Intel 어셈블리 구문에서 대괄호를 사용하여 일관되게 표시됩니다.
st(0)
을 eax
에 저장하는 것과 대조하면 fstp eax
(대괄호 없음)이어야합니다.
후자는 지원되지 않습니다. FPU가 당시에는 레지스터에 맞지 않는 64 비트 및 80 비트 형식을 지원하기 때문일 수 있습니다.
데이터를 푸시하려면. 메모리에서 FPU 스택으로 fld
을 사용하여 레지스터를 메모리로 팝하려면 fstp
(또는 스택을 팝하지 않으려면 fst
)을 사용하십시오.
곱셈 사용 fmul
을 사용하려면 몇 가지 변형이 있으며 그 중 하나는 메모리 피연산자로 연산하고 그 결과를 st(0)
에 직접 저장할 수 있습니다.
편집 초기에 finit
을 사용할 수 있으면이 명령어는 FPU의 제어 레지스터를 재설정하여 레지스터를 비워 둡니다.
OS가 이미 클린 상태로 프로세스를 시작해야합니다. 다음은 간단한 예를
: 오늘로
.DATA
A dd 5.0
B dq 0.008
C dd 0 ;Move into a BSS section if the assembler support it
.CODE
finit ;For paranoid only
fld DWORD [A] ;ST(0) = A
fmul QWORD [B] ;ST(0) = ST(0)*B = A*B
fstp DWORD [C] ;C = ST(0) = A*B
mov eax, DWORD [C] ;EAX = C = A*B
call writefloat
당신은 스칼라 지침 벡터 레지스터를 사용할 수 있습니다.
관련 문서는 이전에 링크 된 Intel 설명서에서 찾을 수 있습니다.
.DATA
A dd 5.0 ;Use float
B dd 0.008 ;Use float again, avoid cvtss2sd
C dd 0 ;Move into a BSS section if the assembler support it
.CODE
movss xmm0, DWORD PTR [A] ;xmm0.f[0] = A
mulss xmm0, DWORD PTR [B] ;xmm0.f[0] = A * B
movd eax, xmm0 ;eax = xmm0.f[0] = A * B
;Beware, 1 extra cycle for bypass delay
call writefloat
이 코드는'fin'을로드하고'fin'을 곱합니다. 그것은 fin^2 (제곱)과 같습니다. 'fmul'는 피연산자로'fin' *을 * 곱할 값을 취해야합니다. 그러나 코드는 질문과 일치하지 않습니다. 왜냐하면'fin'은 상수 5.0이고, 3.02 x 0.008을 곱하는 것을 말합니다. –