2009-11-29 5 views
5

C에서 주소를 나타내는 32 비트 단어가 있습니다. (부호가없는 긴 길이로 저장되었으므로 괜찮습니다). 이제 내가 수집 한 것에서 주소의 일부는 페이지 번호를 포함하고 다른 부분은 오프셋을 포함합니다. 나에게 페이지 번호를주는 비트를 어떻게 추출 할 수 있는지 궁금했다. 나는 이미 처음 22 개의 최상위 비트가 페이지 번호이고 나머지 10 비트가 페이지 오프셋이다. 페이지 번호 인 비트는 어떻게 만듭니 까? 비트 연산으로이 작업을 수행 할 수 있다고 생각하지만 확실하지 않습니다.비트 추출 중

+0

좋은 질문 - 내가 쓰는 디스어셈블러에도이 작업을 수행해야합니다. – new123456

답변

11

bitshift 연산자를 사용하여 필요한 비트를 추출하십시오.

pageNumber = x >> 10; 
offset = x & ((1 << 10) - 1); 

페이지 번호의 경우 >> 연산자가 비트를 아래로 이동하므로 가장 중요한 비트가 손실됩니다.

오프셋의 경우 ((1 < < 10) - 1)는 10 개의 비트로 구성된 비트 마스크를 생성합니다.이 비트 마스크는 10 개의 최하위 비트 만 선택하고 최상위 비트는 무시하는 데 사용됩니다.

+1

하드웨어가 산술 (부호 확장) 오른쪽 시프트를 수행하는 경우를 대비하여 비트를 마스크 한 후에 비트를 마스크하는 것이 좋습니다. 페이지 번호 = (x >> 10) & ((1 << 22) -1); –

2

나는 필드 추출의 "2 교대"방법의 큰 팬이다. 서명과 서명이 모두 작동합니다. word에서 최하위 비트 lsb와 폭 w의 필드를 추출하려면

#define BITSIN(W) (8*sizeof(W)) 
return (word << (BITSIN(word) - (lsb+width))) >> (BITSIN(word) - width); 
이 경우

, BITSIN(word) == 32lsb+width == 32을, 그래서 한 문제의 단어가 서명 한, 당신은 단지 마스크없이 바로 (10)를 전환 할 수 있습니다.

주의 : 32 비트 유형의 경우 32 비트 시프트를주의하십시오.! C 표준은 컴파일러가 어떤 일을 할 수있게 해주고 일반적인 인텔 칩은 유용하지 않다. x << yx 비트가 y % 32 비트만큼 왼쪽으로 변한다 (x은 32 비트 정수형이다). 즉, 32 비트 정수를 왼쪽 또는 오른쪽으로 32 비트 시프트하려고하면 결과는 아무런 연산과 동일하지 않습니다. 64 비트 형식의 64 비트 교대에는 비슷한 문제가 있습니다.

+0

"일반적인 인텔 칩이하는 일은 유용하지 않습니다."- 그들은 무엇을합니까? – AShelly

+0

@cellelly : 좋은 질문입니다. 나는 그 대답을 편집했다. 누가 알면, 그것은 나에게 upvote :-)를 줄지도 모른다. –