2016-09-20 2 views
3

나는 정렬되지 않은 메모리 액세스 문제에 대한 몇 가지 기사를 읽고 언급이 문서 UNALIGNED MEMORY ACCESSESether_addr_equal 함수에 대한 정렬되지 않은 문제?

bool ether_addr_equal(const u8 *addr1, const u8 *addr2) { 
    #ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS 
    u32 fold = ((*(const u32 *)addr1)^(*(const u32 *)addr2)) | 
     ((*(const u16 *)(addr1 + 4))^(*(const u16 *)(addr2 + 4))); 
    return fold == 0; 
    #else 
    const u16 *a = (const u16 *)addr1; 
    const u16 *b = (const u16 *)addr2; 
    return ((a[0]^b[0]) | (a[1]^b[1]) | (a[2]^b[2])) != 0; 
    #endif 
} 

을하며 말했다 해요 :

을하지만 하드웨어에 액세스 할 수 없습니다 때 메모리가 임의의 경계에있는 경우 [0]에 대한 참조는 주소 addr1에서 시작하여 2 바이트 (16 비트)가 메모리에서 읽도록합니다.

글쎄, 나는 그것이 무엇을 의미하는지 모르겠다. 내 마음 속에서 a[0]addr1에서 2 바이트를 읽어야합니다. 그렇지 않다면 무엇을 읽을 것입니까? (아마 충돌,하지만 그것은 2 바이트 또는 아무것도 생각하지 않는 상황입니다). 여기서 어떤 문제가 발생합니까? 그리고 왜 그들은 u8*을 사용하고 정렬되지 않은 문제를 해결하기 위해 1 바이트 씩 비교합니까?

답변

3

내 생각에 [0]은 (는) addr1에서 2 바이트를 읽어야합니다. 그렇지 않다면 무엇을 읽을 것입니까? 여기서 어떤 문제가 발생합니까?

의도 된 의미는 분명하다 a[0]addr1는 하나의 바이트와 2 바이트를 사용하여 액세스 addr1 + 1에서 하나의 바이트를 판독한다. 시스템은 짝수 주소 경계에서 시작하려면 2 바이트 액세스가 필요한 제약이있을 수 있습니다. addr1이 홀수이면 위반됩니다.

그리고 왜 u8 *을 사용하지 않고 정렬되지 않은 문제를 해결하기 위해 1 바이트 씩 비교합니까?

아마도 위의 문제는 대상 시스템에서 발생하지 않는다고 가정했습니다. 한 번에 한 바이트 씩 사용하면이 경우를 처리 할 수 ​​있습니다.


참고 : 기능의 두 반쪽은 기능상 동일하지 않은 것으로 보입니다. 데이터 비트를 모두 0으로 간주하고, 첫 번째는 true을 반환하고, 두 번째는 false을 반환합니다.

+0

_ 아마도 "addr1"과 "addr2"는 적어도 16 비트 정렬이 보장됩니다. "이 정렬을 보장하는 것은 호출자의 몫입니다. 이 기능을 전혀 사용하지 마십시오. " – Notlikethat

+0

@Notlikethat 함수의 두 부분이 서로 다른 기능을 가지고 있기 때문에 함수의 하위 절반이 실제로 사용된다는 것은 의심의 여지가 있습니다. – chux

+1

사실, 누구도 문서를 컴파일 할 수 없다는 것을 확신합니다.) [실제 함수 자체는 정확합니다] (https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/include /linux/etherdevice.h#n305). – Notlikethat