2016-12-24 4 views
-2

에 2 개 개의 float 변수를 곱 방법, 조립 사용자는 3.02로 입력을 입력하고 FPU를 사용하려면이MASM에서 2 개 개의 float 변수를 곱 방법 MASM

.data 
fin dd 5.0 

.code 
main proc 

fld fin 
fmul fin ;to multiply fin with fin 
fstp dword [eax] ;cannot mov result in eax 
call writefloat 

exit 
main EndP 
end main 
+0

이 코드는'fin'을로드하고'fin'을 곱합니다. 그것은 fin^2 (제곱)과 같습니다. 'fmul'는 피연산자로'fin' *을 * 곱할 값을 취해야합니다. 그러나 코드는 질문과 일치하지 않습니다. 왜냐하면'fin'은 상수 5.0이고, 3.02 x 0.008을 곱하는 것을 말합니다. –

답변

0

경우 인쇄 후 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 
+0

답장을 보내 주셔서 감사합니다. 정말 도움이되었습니다. –