2011-11-21 6 views
1

x87 FPU 명령어 디코딩과 관련하여 모호한 경우가 있습니다. Vol 2A Intel의 명령어 세트 매뉴얼 [3]의 3-380 페이지에서 가져온 다음 지시 사항을 살펴보십시오.특정 x87 FPU 명령어 디코딩의 모호성

D9 /0 --> FLD m32fp --> Push m32fp onto the FPU register stack. 
D9 C0+i --> FLD ST(i) --> Push ST(i) onto the FPU register stack. 

이 명령어는 모두 1 바이트 기본 opcode 0xD9과 같습니다. 첫 번째 명령어의 확장 opcode는 0x00입니다. 확장 opcode는 ModR/M 바이트의 'reg'필드에 지정됩니다. 그러나 두 번째 명령은 'Add to register'기능이있는 2 바이트 opcode입니다. 즉, 다음과 같은 의미입니다.

D9 C0 --> FLD ST0 
D9 C1 --> FLD ST1 
(and so on) 

이 두 가지 지침을 구분하는 것과 관련된 작은 문제가 있습니다. 작은 예제는 다음과 같습니다.

이제 opcode 시퀀스 "D9 C1"이 있다고 가정합니다. 명령이 "FLD m32fp"인지 확인해야하는 경우 ModR/M 바이트의 'reg'필드가 0x00인지 확인해야합니다. 그렇다면 실제 사용 지침 "FLD m32fp"이 사용됩니다.

C1의 이진 표현은 "1100 0001"입니다. bit0가 LSB이면, bit3-bit5 (포함)는 ModR/M 바이트 "C1"의 'reg'필드를 구성합니다. 실제로는 0x00 (3 제로)입니다.

그래서 opcode 시퀀스 "D9 C1""FLD m32fp" 명령어로 매핑합니다. 더 자세히 디코딩하면이 경우 피연산자는 실제로 "ecx"이됩니다. 그러나 "FLD ST1"도 opcode 시퀀스 "D9 C1"을 가지고 있으며 이는 해당 opcode 시퀀스에 사용되는 실제 명령어입니다.

본질적으로 opcode 시퀀스 "D9 C1""FLD ST1"이고 "FLD ecx"이 아닌 명령어에 해당하는지 어떻게 확인할 수 있습니까?

"FMUL" 명령어에 대해서도 매우 유사한 문제가 발생합니다. 여기서는 "FLD"과 동일한 방식으로 피연산자를 사용합니다.

[1] http://www.intel.com/design/intarch/manuals/243191.HTM

감사 및 감사
Hrishikesh 무랄리

답변

3

이 설명되어, 해당 부분에 존재 "A.2.6 연산 코드 명령어 탈출."

경우 ModR/M 바이트는 00H에서 BFH의 범위 인 내에 있으며, 1 및 2 바이트 opcode에 사용 된 기술과 유사하게, ModR/M 바이트의 비트 5, 4 및 3이 opcode 확장자로 사용됩니다 섹션 A.2.5., "Op 코드 확장자 1 바이트 및 2 바이트 Opcode "). ModR/M 바이트가 BFH를 통해 00H 의 범위를 벗어나면 전체 ModR/M 바이트가 opcode 확장자로 사용됩니다. 질문에에

는 :

이제 가정하면 나는 오피 순서 "D9 C1"을 얻는다. "FLD m32fp"명령인지 확인해야한다면 ModR/M 바이트의 'reg'필드가 0x00인지 확인해야합니다. 그렇다면 실제로 "FLD m32fp"명령이 사용됩니다.

x87 명령어를 발견하면 mod/rm 바이트가 0xC0 이상인지 확인하십시오 (mod 필드 0b11 또는 3에 해당).이 경우 표 A-10을 참조하십시오. (D9의 경우). 거기를 보면 D9 C1 = FLD ST(0),ST(1)이 보입니다.

mod/rm 바이트가 < 0xC0이면 사용할 테이블은 A-9입니다. D9 01 (mod = 0b00, opcode 확장 (reg) = 0b000, rm = 0b001)은 "FLD 단일 실수"이며, 표 2-2를 보면 fld dword [ecx]이됩니다.

정수 레지스터에서 FPU 스택으로 직접로드 할 수 없으므로 "FLD ecx"와 같은 명령어는 없습니다.

+0

감사합니다. 이것은 정말로 나를 이해하는 데 도움이되었습니다. :-) 그래서이 검사 '> = C0'은 모든 명령에 적용 할 수 있습니까? 또는 FPU 관련 명령어에만 해당됩니까? –

+0

이것은 x87 명령어에만 해당됩니다. 당신은 기본적으로'mod = 0b11'을 먼저 검사하고, 그 경우에는 64 개 큰 테이블 (modrm & 0x3F)에서 명령어를 검색하고, 그렇지 않으면 reg 필드를 사용하여 명령어를 결정하고 rm 필드에서 피연산자를 확인하기를 원할 것입니다. – user786653

+0

흠, 좋아. 감사! :-) –