MSIL을 살펴보고 MSIL에 nop 지침 이 많이 있음을 알았습니다 .
MSDN 기사는 조치를 취하지 않으며 opcode가 패치되면 공간을 채우는 데 사용됩니다. 릴리스 빌드보다 디버그 빌드에서 더 많이 사용됩니다.
이러한 종류의 문이 어셈블리 언어에서 나중에 명령을 정렬하는 데 사용된다는 것을 알고 있지만 MSIL에서 MSIL nops가 필요한 이유는 무엇입니까?
(편집자 주 : 수락 된 답변은 질문이 원래 질문 한 MSIL / CIL NOP가 아니라 기계 코드 NOP에 관한 것입니다.)
답변
NOP는 여러 가지 용도로 사용됩니다.
- 이를 통해 생성 된 코드에서 다른 행과 결합 된 경우에도 디버거가 한 행에 중단 점을 배치 할 수 있습니다.
- 로더가 다른 크기의 타겟 오프셋으로 점프를 패치 할 수 있습니다.
- 이를 통해 코드 블록을 특정 경계에 정렬 할 수 있으므로 캐싱에 유용 할 수 있습니다.
- 전체 함수 변경 크기에 대해 걱정할 필요없이 새 섹션에 대한 호출로 코드 청크를 덮어 쓰는 증분 링크를 허용합니다.
답변
다음 은 디버깅에서 MSIL / CIL nops ( x86 기계 코드nop
아님)를 사용하는 방법입니다.
Nops는 암시 적 시퀀스 포인트를 정의하기 위해 언어 컴파일러 (C #, VB 등)에서 사용됩니다. 이것들은 기계 명령어가 IL 명령어로 다시 매핑 될 수 있도록 JIT 컴파일러에 알려줍니다.
DebuggingModes.IgnoreSymbolStoreSequencePoints 에 대한 Rick Byer의 블로그 항목 은 몇 가지 세부 정보를 설명합니다.
C #은 또한 호출 명령 뒤에 Nops를 배치하므로 소스의 반환 사이트 위치가 호출 이후의 라인이 아닌 호출이됩니다.
답변
릴리스 빌드가 아무 것도 방출하지 않는 코드에서 라인 기반 마커 (예 : 중단 점)에 대한 기회를 제공합니다.
답변
또한 특정 프로세서 또는 아키텍처를 최적화 할 때 코드 실행 속도를 높일 수 있습니다.
오랫동안 프로세서는 대략 병렬로 작동하는 여러 파이프 라인을 사용하므로 두 개의 독립적 인 명령을 동시에 실행할 수 있습니다. 두 개의 파이프 라인이있는 단순 프로세서에서 첫 번째는 모든 명령어를 지원할 수있는 반면 두 번째는 하위 집합 만 지원합니다. 또한 아직 완료되지 않은 이전 명령의 결과를 기다려야 할 때 파이프 라인 사이에 약간의 지연이 있습니다.
이러한 상황에서 전용 nop 는 다음 명령어를 특정 파이프 라인 (첫 번째 파이프 라인 또는 첫 번째 파이프 라인 아님)으로 강제 적용하고 다음 명령어의 페어링을 개선하여 nop 의 비용 이 상각 된 금액 이상이 되도록합니다 .
답변
친구! No-op은 굉장합니다! 시간 만 소비하는 명령입니다. 희미한 암흑 시대에는 중요한 루프에서 타이밍을 미세 조정하는 데 사용하거나 더 중요한 것은 자체 수정 코드의 필러로 사용합니다.
답변
최근에 작업 한 한 프로세서에서 (4 년 동안) NOP를 사용하여 다음 작업이 시작되기 전에 이전 작업이 완료되었는지 확인했습니다. 예를 들면 :
등록 할 값로드 (8주기 소요) nop 8 레지스터에 1 추가
이것은 레지스터가 추가 작업 전에 올바른 값을 가지고 있는지 확인했습니다.
또 다른 용도는 특정 크기 (32 바이트)가되어야하는 인터럽트 벡터와 같은 실행 단위를 채우는 것입니다. 필요합니다.
답변
디버깅하는 동안 편집 및 계속 을 지원하는 데 사용할 수 있습니다 . 디버거에 오프셋 등을 변경하지 않고 이전 코드를 새 코드로 교체 할 수있는 공간을 제공합니다.