짧은 답변: 사용 가능한 주소의 수는 다음 중 작은 수와 같습니다.
- 메모리 크기 (바이트)
- CPU의 기계어에 저장할 수있는 가장 큰 부호없는 정수
위의 긴 대답과 설명 :
메모리는 바이트 (B)로 구성됩니다. 각 바이트는 8 비트로 구성됩니다 (b).
1 B = 8 b
1GB RAM은 실제로 1 GiB (기가 바이트가 아닌 기가비트)입니다. 차이점은 다음과 같습니다.
1 GB = 10^9 B = 1 000 000 000 B
1 GiB = 2^30 B = 1 073 741 824 B
메모리의 모든 바이트는 CPU 머신 워드의 크기와 상관없이 자체 주소를 가지고 있습니다. 예 : Intel 8086 CPU는 16 비트 였고 메모리를 바이트 단위로 처리 했으므로 최신 32 비트 및 64 비트 CPU를 사용하십시오. 이것이 첫 번째 제한의 원인입니다. 메모리 바이트보다 많은 주소를 가질 수 없습니다.
메모리 주소는 CPU가 메모리의 처음부터 건너 뛸 바이트 수입니다.
- 첫 번째 바이트에 액세스하려면 0 바이트를 건너 뛸 수 있으므로 첫 번째 바이트의 주소는 0입니다.
- 두 번째 바이트에 액세스하려면 1 바이트를 건너 뛰어야하므로 주소는 1입니다.
- (기타 등등...)
- 마지막 바이트에 액세스하기 위해 CPU는 1073741823 바이트를 건너 뜁니다. 따라서 주소는 1073741823입니다.
이제 32 비트가 실제로 무엇을 의미하는지 알아야합니다. 앞에서 언급했듯이 기계 단어의 크기입니다.
기계어 란 CPU가 숫자를 저장하는 데 사용하는 메모리 양 (RAM, 캐시 또는 내부 레지스터)입니다. 32 비트 CPU는 32 비트 (4 바이트)를 사용하여 숫자를 저장합니다. 메모리 주소도 숫자이므로 32 비트 CPU에서 메모리 주소는 32 비트로 구성됩니다.
이제 이것에 대해 생각해보십시오. 하나의 비트가 있다면 0 또는 1의 두 값을 저장할 수 있습니다. 하나 더 비트를 추가하면 네 개의 값인 0, 1, 2, 3이 있습니다. 3 비트에서 8 개의 값을 저장할 수 있습니다 : 0, 1, 2 ... 6, 7. 이것은 실제로 바이너리 시스템이며, 다음과 같이 작동합니다 :
Decimal Binary
0 0000
1 0001
2 0010
3 0011
4 0100
5 0101
6 0110
7 0111
8 1000
9 1001
10 1010
11 1011
12 1100
13 1101
14 1110
15 1111
이것은 보통의 덧셈과 똑같이 작동하지만 최대 숫자는 9가 아닌 1입니다. 10 진수는 0입니다. 0000
, 1을 더하고 get 0001
, 한번 더 추가하면 0010
. 여기서 일어난 일은 십진법을 갖는 것과 같습니다. 09
하나 추가 : 9를 0으로 변경하고 다음 자릿수를 증가시킵니다.
위의 예에서 상수 값을 가진 숫자에는 항상 최대 값이 있음을 볼 수 있습니다. 모든 비트가 1이고 값을 1 씩 늘리려고하면 모든 비트가 0이되어 번호. 이는 정수 오버플로라고 불리며 사용자와 개발자 모두에게 많은 불쾌한 문제를 일으 킵니다.
11111111 = 255
+ 1
-----------
100000000 = 0 (9 bits here, so 1 is trimmed)
- 1 비트의 경우 최대 값은 1이며,
- 2 비트 - 3,
- 3 비트 - 7,
- 4 비트 - 15
가능한 최대 수는 항상 2 ^ N-1입니다. 여기서 N은 비트 수입니다. 앞에서 말한 것처럼 메모리 주소는 숫자이며 최대 값을가집니다. 그렇기 때문에 기계어의 크기가 사용 가능한 메모리 주소의 수에 대한 제한이기도합니다. 가끔씩 CPU가 더 많은 메모리를 처리 할만큼 큰 숫자를 처리 할 수없는 경우가 있습니다.
따라서 32 비트에서 0에서 2 ^ 32-1까지의 숫자를 유지할 수 있으며 4 294 967 295입니다. 1GB RAM에서 가장 큰 주소보다 많기 때문에 특정 경우에 RAM의 양이 제한 요소가됩니다.
32 비트 CPU의 RAM 제한은 이론적으로 4GB (2 ^ 32)이며 64 비트 CPU의 경우 16 EB (엑사 바이트, 1 EB = 2 ^ 30 GB)입니다. 즉, 64 비트 CPU는 전체 인터넷을 처리 할 수 있습니다 ... 200 번;) ( 울프 램 알파 ).
그러나 실제 운영 체제에서 32 비트 CPU는 약 3 GiB의 RAM을 처리 할 수 있습니다. 운영 체제의 내부 아키텍처 때문입니다. 일부 주소는 다른 용도로 예약되어 있습니다. 이 소위에 대해 더 많이 읽을 수 있습니다. Wikipedia의 3GB 장벽 . 이 한도를 실제 주소 확장 .
메모리 어드레싱에 관해서는 언급해야 할 몇 가지 사항이 있습니다. 가상 메모리 , 분할 과 페이징 .
가상 메모리
@Daniel R Hicks이 또 다른 대답으로 지적한 것처럼 OSes는 가상 메모리를 사용합니다. 이것이 의미하는 것은 응용 프로그램이 실제로 실제 메모리 주소에서 작동하는 것이 아니라 OS에서 제공하는 것입니다.
이 기술을 통해 운영 체제는 RAM에서 소위 페이지 파일 (Windows) 또는 스왑 (* NIX)으로 일부 데이터를 이동시킬 수 있습니다. HDD는 RAM보다 속도가 느리지 만 드물게 액세스되는 데이터에는 심각한 문제가 아니며 OS가 실제로 설치 한 것보다 많은 RAM을 응용 프로그램에 제공 할 수 있습니다.
페이징
지금까지 우리가 얘기 한 것은 평면 주소 지정 체계라고합니다.
페이징은 평면 모델에서 일반적으로 한 기계 단어로 할 수있는 더 많은 메모리를 처리 할 수있는 대체 주소 지정 체계입니다.
4 글자 단어로 가득 찬 책을 상상해보십시오. 각 페이지에 1024 개의 숫자가 있다고 가정 해 보겠습니다. 번호를 지정하려면 두 가지를 알아야합니다.
- 해당 단어가 인쇄되는 페이지 번호입니다.
- 그 페이지에서 당신이 찾고있는 단어는 어느 것입니까?
이제 그것이 바로 최신 x86 CPU가 메모리를 처리하는 방법입니다. 그것은 4 KiB 페이지 (각각 1024 기계 단어)로 나뉘며 그 페이지에는 숫자가 있습니다. (실제로 페이지는 4 MiB 또는 2 MiB가 될 수 있습니다. PAE ). 메모리 셀을 주소 지정하려면 해당 페이지에서 페이지 번호와 주소가 필요합니다. 각 메모리 셀은 정확히 한 쌍의 숫자로 참조되며 세그멘테이션에는 해당되지 않습니다.
분할
글쎄, 이것은 페이징과 아주 비슷하다. 그것은 하나의 예제를 명명하기 위해 인텔 8086에서 사용되었습니다. 주소 그룹은 페이지가 아닌 메모리 세그먼트라고합니다. 차이점은 세그먼트가 겹칠 수 있으며 중복되는 부분이 많다는 것입니다. 예를 들어 8086에서 대부분의 메모리 셀은 4096 개의 다른 세그먼트에서 사용할 수있었습니다.
예 :
우리가 8 바이트의 메모리를 가지고 있다고 가정 해 봅시다. 모두 4 번째 바이트를 제외하고는 0을 가지고 있습니다. 이것은 255와 같습니다.
평면 메모리 모델에 대한 그림 :
_____
| 0 |
| 0 |
| 0 |
| 255 |
| 0 |
| 0 |
| 0 |
| 0 |
-----
페이징 메모리에 대한 그림 4 바이트 페이지 :
PAGE0
_____
| 0 |
| 0 |
| 0 | PAGE1
| 255 | _____
----- | 0 |
| 0 |
| 0 |
| 0 |
-----
세그먼트 화 된 메모리에 대한 그림 4 바이트 세그먼트가 1 :
SEG 0
_____ SEG 1
| 0 | _____ SEG 2
| 0 | | 0 | _____ SEG 3
| 0 | | 0 | | 0 | _____ SEG 4
| 255 | | 255 | | 255 | | 255 | _____ SEG 5
----- | 0 | | 0 | | 0 | | 0 | _____ SEG 6
----- | 0 | | 0 | | 0 | | 0 | _____ SEG 7
----- | 0 | | 0 | | 0 | | 0 | _____
----- | 0 | | 0 | | 0 | | 0 |
----- ----- ----- -----
보시다시피 네 번째 바이트는 네 가지 방식으로 처리 할 수 있습니다. (0부터 주소 지정)
- 세그먼트 0, 오프셋 3
- 세그먼트 1, 오프셋 2
- 세그먼트 2, 오프셋 1
- 세그먼트 3, 오프셋 0
항상 같은 메모리 셀입니다.
실제 구현에서 세그먼트는 1 바이트 이상 이동합니다 (8086의 경우 16 바이트).
세분화에 대해 나쁜 점은 복잡하다는 것입니다 (그러나 나는 이미 알고 있다고 생각합니다.) 좋은 점은 모듈 식 프로그램을 만드는 데 영리한 기술을 사용할 수 있다는 것입니다.
예를 들어, 일부 모듈을 세그먼트에로드 한 다음 세그먼트가 실제 크기보다 작다고 가정하고 (모듈을 보유 할 정도로 작음) 의사 크기가 작은 세그먼트와 겹치지 않는 첫 번째 세그먼트를 선택하고 다음 모듈을로드하십시오 , 등등. 기본적으로이 방법은 가변 크기의 페이지입니다.