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 무랄리
감사합니다. 이것은 정말로 나를 이해하는 데 도움이되었습니다. :-) 그래서이 검사 '> = C0'은 모든 명령에 적용 할 수 있습니까? 또는 FPU 관련 명령어에만 해당됩니까? –
이것은 x87 명령어에만 해당됩니다. 당신은 기본적으로'mod = 0b11'을 먼저 검사하고, 그 경우에는 64 개 큰 테이블 (modrm & 0x3F)에서 명령어를 검색하고, 그렇지 않으면 reg 필드를 사용하여 명령어를 결정하고 rm 필드에서 피연산자를 확인하기를 원할 것입니다. – user786653
흠, 좋아. 감사! :-) –