2010-01-12 3 views
1

우리 모두 알고 있듯이 .NET에서 정수가 오버플로 될 때마다 IntegerOverflow 예외가 발생합니다. 나는 이것이 아주 좋은 것이라고 생각한다..NET VM이 정수 오버플로를 검사하는 방법은 무엇입니까?

하지만 어떻게하면 이렇게 빨리 만들 수 있을지 궁금합니다. x86은 정수 오버 플로우를 함정에 빠뜨리지 않으며, 다른 아키텍처가 그렇게 할 수 있다면 놀랄 것입니다. 내가 x86에서 찾은 가장 좋은 해결책은 모든 단일 산술 연산 후에 "INTO"명령어를 넣는 것입니다. 그러나 나는 이것이 눈에 띄게 둔화 될 것이라고 생각합니다.

컴파일러에서 정적 검사를 수행하여 오버플로가 될 수없는 경우에이를 방지 할 수 있습니다. 그러나 컴파일러가 작업 결과를 결정할 수 없을 때 성능에 중요한 내부 루프는 어떻게됩니까?

모노 소스를 보려고했지만이 수표를 수행하는 곳을 찾을 수 없었습니다.

누구나 실제로 어떤 일을하는지 알 수 있습니까? 나는 정말로 알고 싶다.

사이드 노트 : .NET JITC가 방출하는 x86 코드를 볼 수있는 방법이 있습니까?

+0

"정수가 넘칠 때마다": IL 명령의 * checked form *을 사용할 때만. 'add'보다는'add.ovf'를 사용하십시오. 확인 된 키워드를 사용하지 않으면 기본적으로 C#이 생성하는 검사되지 않은 지침이 있습니다. C에서 "알고 사랑하는"방식으로 오버플로가됩니다. – itowlson

+1

NGEN에서 원시 이미지 기계 코드 ... http://msdn.microsoft.com/en-us/library/6t9t5wcf%28VS.80%29.aspx –

+0

큰 벌칙이 아닙니다. 오버 플로우 예외가 거의 발생하지 않으면 프로세서는 해당 분기를 올바르게 예측하기 시작하며 루프 성능이 걱정된다고 가정 할 경우 속도가 느려지 게됩니다. – Yuliy

답변

2

소스 또는 프로젝트의 설정 (언어에 따라 다름) 중 체크 된 컨텍스트에있는 경우에만 발생합니다. 그 결과 다른 일리노이 명령을 내 보냅니다.

이것은 일반적인 문제가있는 arithmetic overflow의 특정 예일 뿐이며 x86 JIT 구현에서는 플래그가 설정된 경우 예외를 throw하라는 지시와 함께 이러한 연산을 수행 한 후 의심 할 여지없이 관련 플래그를 삽입합니다. (예를 들어 추가 사용)

지침은 다음과 같습니다

  • add
  • add.ovf.un 추가하는 두 개의 번호를 추가 할 수
  • add.ovf 트랩 서명 오버플로 (오버플로 주위 랩) 두 숫자를 추가 두 숫자와 함정 부호없는 오버플로

실제로 컴파일러 확인의 특정 수준이 있습니다 스 태트 폴딩이 발생하고 결과 값이 지정된 변수에 맞아야합니다. 다른 정적 분석 측정도 가능하지만 갇힐 수있는 것에는 한계가 있습니다.

방출 된 JIT 코드를 보려면 혼합 모드에서 관련 코드를 간단히 디버그하고 일반 프로그램과 마찬가지로 디스 어셈블리, 스택, 레지스터를 살펴보십시오. 또는 ngen 이미지를 살펴보십시오 (형식이 변경되기 쉽지 않으므로 까다 롭습니다).

VS를 통해이 작업을 수행하는 경우 디버거가 연결되어 있는지 여부와 어셈블리가 있는지 여부에 따라 JIT 결과가 달라 지므로 디버거를 연결하여 정상적으로 프로그램을 시작할 수 있습니다. 허용되지 않는 최적화 (디버그 빌드의 기본값)로 표시

3

디버깅을 시작하고 소스를 마우스 오른쪽 버튼으로 클릭하여 디스 어셈블리로 이동합니다.

 int ix = int.MaxValue; 
0000003a mov   dword ptr [ebp-40h],7FFFFFFFh 
     int jx = 1; 
00000041 mov   dword ptr [ebp-44h],1 
     Console.WriteLine(ix + jx); 
00000048 mov   ecx,dword ptr [ebp-40h] 
0000004b add   ecx,dword ptr [ebp-44h] 
0000004e jno   00000055     <--- overflow test 
00000050 call  6D7ABAD2     <--- kaboom 
00000055 call  6CFE2F40 

즉, JIT 컴파일러는 오버플로를 확인하기 위해 명시 적 코드를 생성합니다. 기본적으로 해제되어 있습니다.

관련 문제