2016-07-20 7 views
1

x86에서 멀티 바이트 오브젝트가 메모리 리틀 엔디안 스타일로 저장된다는 것을 알고 있습니다.Linux x86 CPU 명령어 레이아웃 혼동

일반적으로 말하자면 CPU 명령어의 경우 OPCODE가 명령어의 용도를 결정하고 데이터/메모리 주소가 인코딩 된 형식의 opcode를 따를 수 있습니다. 필자의 이해는 명령어의 Opcode 부분이 최상위 바이트 여야하므로 주어진 명령어 인코딩 표현의 최상위 주소에 나타납니다.

누군가이 x86 linux gdb 예제에서 메모리 레이아웃을 설명 할 수 있습니까? opcode 0xb8이 가장 중요한 바이트이기 때문에 더 높은 주소에 나타날 것이라고 생각합니다.

(gdb) disassemble _start 

Dump of assembler code for function _start: 
0x08048080 <+0>: mov eax,0x11223344 

(gdb) x/1xb _start+0 
0x8048080 <_start>:  0xb8 
(gdb) x/1xb _start+1 
0x8048081 <_start+1>: 0x44 
(gdb) x/1xb _start+2 
0x8048082 <_start+2>: 0x33 
(gdb) x/1xb _start+3 
0x8048083 <_start+3>: 0x22 
(gdb) x/1xb _start+4 
0x8048084 <_start+4>: 0x11 

mov movx, 0x11223344 명령어는 0x11 0x22 0x33 0x44xxxx로 인코딩됩니다.

질문

1.) 첫 번째 바이트가 opcode가 아닌 경우 명령어가 차지할 바이트 수를 CPU가 어떻게 알 수 있습니까?

2.) 아마도 x86 CPU 명령어가 엔디안 - 네스 (endian-ness)조차 갖고 있지 않으며 일부 유형의 문자열을 고려하고 있는지 궁금합니다. (아마 여기서 떨어져)

+1

# 2가 정확합니다.지침에는 엔디안이 없지만 임베디드 상수는 포함되어 있습니다. gdb 덤프에서 볼 수 있듯이 opcode **는 첫 번째 바이트입니다 (단, 앞에 접두어 바이트가 올 수 있습니다). 참고 항목 _Intel® 64 및 IA-32 아키텍처 소프트웨어 개발자 설명서 제 2 권 : 명령어 세트 참조 서, AZ 제 2 장 명령어 형식 – Jester

+0

다중 바이트 정수를 메모리와 관련하여 2 바이트 이상을 포함하는 CPU 명령어와 혼동시킬 수 있습니다 표현 – htederson

+0

Jester는 opcode가 인코딩 된 명령어의 첫 번째 바이트임을 지적합니다. – htederson

답변

5

x86은 가변 길이 명령어 세트입니다. 엔디안이없는 단일 바이트로 시작해야합니다.

opcode에 따라 더 많은 바이트가있을 수 있으며 예를 들어 32 비트 즉치 일 수 있습니다 (해당 바이트 그룹이 일종의 즉치 또는 주소 인 경우).이 바이트는 리틀 엔디안입니다. 5 바이트 ABCDE (엔디안 없음, 배열 또는 문자열 생각)가 있다고 가정 해보십시오. A 바이트는 연산 코드이며, B 바이트는 즉치의 하위 8 비트이고 E는 즉치의 상위 8 비트입니다.

Opcode는 사용하기 힘든 용어입니다. x86과 같은 이전의 8/16 비트 CISC 프로세서에서 전체 바이트는 기본적으로 테이블에서 무엇을 의미하는지 (그리고 사용했던 프로세서 내부에서) 찾은 opcode였습니다 테이블을 실행하는 방법을 이해하는 테이블). MIPS 나 ARM이나 다른 RISC (확실한 RISC) 명령어 세트를 보면 32 비트 중 일부만이 "opcode"이고 어느 경우도 한 명령어에서 다른 명령어로의 비트 세트가 같지 않습니다. (예, 디코딩을 정상적으로하기 위해 오버랩이 있음) MIPS는 훨씬 더 일관성이 있습니다. 한 곳에서 한 면만 볼 수 있지만 그 중 하나의 패턴은 다른면을보아야합니다. 비트를 완전히 디코딩해야합니다. ARM은 일반적인 비트로 시작합니다. 길 건너가는 길에서 명령어를 추가로 디코딩하면 완전히 디코딩 할 수있는 무작위로 보이는 부분을 잡아야 할 수도 있습니다. 나머지 비트는 피연산자입니다. 어떤 레지스터를 사용할지 또는 즉각적으로 또는 CISC에서 룩업 테이블을 필요로하는지 (opcode에 의해 암시되지만 op 코드의 비트에 의해 정의되지는 않음) 종류가 무엇이든간에.

1) 이전 명령 다음의 다음 바이트는 하나가 아니더라도 (연산이 해당 바이트와 분기를 계속하는 경우) opcode로 해석됩니다. 나는 정의되지 않은 명령어가 있는지 없는지 알기 위해 내 x86 테이블을 기억하지 못한다. 정의되지 않았다면 핸들러를 쳐야한다. 그렇지 않으면 머신 코드로 찾은 것을 디코드 할 것이고 제대로 작성되지 않은 명령어는 충돌 할 가능성이있다. 때로는 운이 좋으면 무언가를 엉망으로 만들고 계속 나아가거나 심지어 운이 좋으면 거의 추락했다고 말할 수 없습니다.

2)이 8/16 비트 CISC 또는 이와 유사한 명령어 세트의 경우 올바른 것으로 간주됩니다.이 명령어 세트는 선형 분석을 통해 더 많은 문자열로 처리됩니다.

+0

예 ARM과 MIPS가 코어 중 일부에서 16 비트 대체 명령어 세트를 가지고 있음을 잘 알고 있습니다. 가변 길이 16 비트 명령어 세트 (엄지 2 확장 기능)로 ARM이 더욱 악화됩니다. 플러스 모든 부동 소수점 물건, 어쩌면 자바 것, 등등 그냥 고정 된 32 비트 명령에 대한 이야기 ​​위의 목적을 위해 좋습니다. 인터넷 검색을하는 경우 밉 및 팔의 인코딩을 찾아야하며 아마도 디코딩 방법을 "볼"수 있습니다. 둘 다 서로 다른 디자인 방식을 사용합니다. –

+0

감사합니다 dwelch, 고맙습니다. – htederson

+0

질문 1)에 대답하지 않았을 수도 있습니다. cpu가 읽는 opcode가 어떻게되는지를 알 수 있습니다. 그것은 opcode 및/또는 그 명령에 필요한 총 바이트 수를 따르는 추가 바이트를 알고 있습니다. 가변 길이이므로 일부 명령어는 1 바이트만큼 짧고 다른 명령어는 비교적 길 수 있습니다. 나는 가장 긴 인텔 지시가 인 것의 질문이 흥미있는 IMO가 아니라 여러 사람에게 여러 번 물었다라고 생각한다. 그러나 일부 사람들은 따라 놀았다. –