2014-09-18 2 views
1

여기 내 코드입니다 :ARM은 정렬되지 않은 예외를 생성하지 않습니다

char data[5] = {0x1, 0x2, 0x3, 0x4, 0x5 }; 
int *ptr = (int *)(data + 1); 
int value = *ptr; 

printf("address of data= %lu\n",data); 
printf("address of data +1 = %lu\n",data+1); 

내가 사용 컴파일 할 GCC -Wcast-정렬이 경고 "대상 유형의 정렬을 필요 캐스트 증가"방출, ARM을 위해.

그러나 ARM 프로세서에서 실행할 때 은 정렬되지 않은 액세스 예외을 생성하지 않습니다.

printf는 데이터가 4의 배수 인 주소에 위치하므로 데이터 + 1은 정렬되지 않은 예외를 생성해야하는 홀수 주소임을 나타냅니다.

/proc/cpu/alignment를 3으로 설정했습니다. dmesg에서 메시지를받지 못했습니다.

예외가 발생하지 않는 이유는 무엇입니까?

+0

데이터 배열이 4의 배수 인 주소에 정렬되도록하려면 어떻게해야합니까? 디버깅 중에 검사 할 때 데이터 배열의 실제 주소는 무엇입니까? 어떤 ARM CPU입니까? – Malkocoglu

+0

팔 버전 7입니다. 질문을 편집하여 데이터 주소를 인쇄 해 보겠습니다. – linuxfreak

+0

팔 (밉스 등)은 역사적으로 정렬되지 않은 전송에 대해 낙담하고 잘못했기 때문에 항상 볼 수 있다는 의미는 아니며 이벤트를 사용 중지 할 수 있으며 코어에 따라 정렬되지 않은 전송에서 반환 된 데이터는 결정적입니다 (최신 코어는 프로그래머가 기대하는 것처럼). 성능상의 불이익은 자연스럽게 x86과 같습니다. –

답변

4

커널에서 (실제로는 실제로 하드웨어에서 올바르게 작동하는 예외를 발생시키는 데 약간의 요점이 있으므로 ARMv6 + 정렬되지 않은 액세스 모델이 적용되는 곳) always clears the SCTLR.A bit (부분은 if (cpu_is_v6_unaligned())...입니다.) 정렬되지 않은 경우 LDM/STM과 같이 완전히 무효 인 명령어에 대해서만 예외가 발생합니다.

+2

쉽게'cat/proc/cpu/alignment'에 의해 확인됩니다. * User * 카운트가 주식 커널로 증가하지 않는다면 그것은 일어나지 않습니다. –

3

1 : 커널이 항상 데이터 유형 < = 32 비트에 대한 정렬되지 않은 액세스를 허용하고/proc 설정을 무시합니다.

2 : 생성 된 어셈블리 코드를 확인 했습니까? 컴파일러는 ptr 변수를 최적화하고 memcpy를 사용하여 & 데이터 [1]에서 & 값까지의 4 바이트를 얻을 수 있습니다. 이렇게하면 설정에 관계없이 절대로 예외를 얻을 수 없습니다. 정렬되지 않은 액세스가 감지되면 ARM 컴파일러가 Cortex-M3 대상에 대해 이렇게했습니다!

+3

두 번째 포인트는 또 다른 컨텍스트에서 true를 나타냅니다. 정렬되지 않은 액세스를 유발할 수있는 모든 것은 C에서 정의되지 않은 동작이므로 컴파일러는 완벽하게 자유로 워서 아무 것도 생성하지 않습니다 그렇게 할 코드. – Notlikethat