간단한 명령어 인코딩
다음 어셈블리 지침을 살펴 보겠습니다.
add %cl,%bl
이것은 00 cb또는 00000000 11001011바이너리 로 인코딩됩니다 . cbModR / M 비트 필드에를 넣으면 다음과 같습니다.
1 1 0 0 1 0 1 1
+---+---+---+---+---+---+---+---+
| mod | reg | r/m |
+---+---+---+---+---+---+---+---+
그리고 여기 에서 레지스터 필드를 조회하면 다음과 같은 결과 를 얻을 수 있습니다.
- mod :
11(주소 지정 모드 등록) - reg :
001(cl 레지스터) - r / m :
011(bl 레지스터)
그리고, 저는 믿습니다 000000ds은 IS add명령, 그리고 d=s=0그들은 모든 레지스터는 것 때문이다. 이 명령이 인코딩되는 방법에 대한 올바른 이해입니까? 또한 '전체 인코딩'체계의 경우 다음이 정확합니다 (비트가 아닌 바이트).
[empty] 0x0 0b11001011 [empty] [empty] [empty]
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
Prefix Instruction Mod-reg-r/m Scale displacement immediate
명령을 '디코딩'하려는 시도에서 여기에 누락 된 것이 있습니까?
답변
네, 맞아요.
인코딩 op r/m, r대 op r, r/m, 및 8 비트 대 16/32 비트를 위한 일반 패턴 (8086으로 거슬러 올라가는 "레거시"ALU 명령어 의 경우)은 일반 패턴에서 opcode 바이트의 하위 2 비트를 사용하지만 그럴 필요는 없습니다. 그것에 의존합니다.
인텔은 vol.2 매뉴얼에서 각 명령어의 각 인코딩에 대해 진행되는 작업을 정확히 문서화합니다. add예를 들어 Op / En 열 및 피연산자 인코딩 표를 참조하십시오 . (또한보십시오https://ref.x86asm.net/coder64.htm이는 또한 모든 opcode에 대해 어떤 피연산자를 지정합니다). 둘 다 ModRM 바이트를 사용하는 opcode와 그렇지 않은 opcode를 알려줍니다.
물론 이들은 Intel 구문 순서를 사용합니다. 피연산자 목록과 Intel 및 AMD 매뉴얼의 순서를 반대로하는 AT & T 구문을 사용하면서 매뉴얼과 튜토리얼을 따라 가면서 삶을 더 복잡하게 만들고 있습니다.
예를 들어 , 피연산자 인코딩 00 /r으로 나열 되며 MR, 테이블에서 피연산자 1 = ModRM:r/m (r, w)이므로 읽고 쓰고 r/m필드에 의해 인코딩됩니다 . 피연산자 2 = ModRM:reg (r)이므로 reg필드로 인코딩 된 읽기 전용 소스 입니다.
재미있는 사실 : 00 00is add [rax], al또는 AT & Tadd %al, (%rax)
GAS에 다음 인코딩 중 하나를 선택하도록 요청할 수 있습니다. x86 XOR opcode 차이
{load} add %cl,%bl # 02 d9
{store} add %cl,%bl # 00 cb
MOV r / m8, r8과 MOV r8, r / m8의 차이점 도 참조하십시오.