2014-12-23 10 views
-1

가 다음 코드 조각을 등록하여 분할 : 나는 그것을 컴파일하려고하면fidiv : 잘못된 피연산자 유형 오류

void calculate(int int_number) { 
    __asm { 
     fld1 
     mov eax, 5 
     fidiv eax ; A 
    } 
} 

의 선은 error C2415: improper operand type와 함께 실패합니다. eax을 정수 상수로 바꾸면 같은 문제가 발생합니다. 나는 fidiv 매개 변수로 int_number를 통과 할 경우, :

void calculate(int int_number) { 
    __asm { 
     fld1 
     fidiv int_number 
    } 
} 

코드가 제대로 컴파일합니다.

그래서 레지스터로 나누는 것이 잘못된 이유는 무엇입니까?

Windows 8.1 64 비트에서 Visual Studio를 사용하고 있습니다.

+2

기계 명령어 'fidiv'는 레지스터에 적용 할 수 없습니다. 간접 어드레싱을 사용하여 메모리에서 피연산자를로드해야합니다. 유일한 인수는'dword ptr CONSTANT [REGISTER]'형식이어야합니다. 'fidiv '를 쓸 때 컴파일러는 함수의 스택 프레임의 레이아웃에 따라'fidiv dword ptr OFFSET [ebp]'로 바꿉니다. – ach

답변

1

답변에도 불구하고 이미 : 피연산자는 메모리 피연산자 여야합니다. 설명서의

봐, 그것은 말한다 :

DA/6 그것은 당신이 선택할 수있는 경우가있을 것이다 FIDIV r/m32int을 나열하지 않습니다

FIDIV m32int
DE/6 FIDIV m16int 해당 피연산자에 대해서도 등록하십시오. FPU 명령어의 일부 그룹 (첫 번째 바이트를 기반으로하는 그룹)은 다른 명령어가있는 두 개의 하위 그룹으로 분할됩니다 (모든 그룹은 분할되지만 일부는 D8과 같이 일부는 피연산자에 따라 다른 두 개의 하위 그룹으로 나뉩니다). DADE 그룹은 근본적으로 다른 두 개의 하위 그룹으로 나뉘는 그룹의 예입니다. 그룹은 ModR/M 바이트의 "mod"필드를 기준으로 분할되지만 00은 10이지만 한 그룹은 11이지만 다른 그룹은 11입니다.

두 번째 그룹이 "정상"인 그룹에서 mod 필드 11은 ST (i) 피연산자의 사용을 나타냅니다. "기묘한"그룹에서는 지시가 완전히 다른 것을 의미합니다.

예를 들어 DA F0FIDIV eax을 의미 할 수도 있지만 실제로는 아무 것도 의미하지 않습니다. 거기에 테이블에 구멍이 있습니다. 반면에 DA C0
FIADD eax을 의미 할 수도 있지만 실제로는 FCMOVB st(0), st(0)을 의미합니다.