C언어 32 vs 64비트 시스템에서의 컴파일 차이

Kiwoong Park·2023년 3월 28일
0

32 vs 64비트 스택 메모리의 데이터와 주소 숫자의 역순 관계

32비트 시스템에서는 스택 메모리가 데이터가 쌓일수록 주소가 감소하므로, 스택 메모리의 bottom 주소가 가장 높은 주소를 가리키고, top 주소가 가장 낮은 주소를 가리킵니다.

반면에, 64비트 시스템에서는 스택 메모리가 데이터가 쌓일수록 주소가 증가하므로, 스택 메모리의 bottom 주소가 가장 낮은 주소를 가리키고, top 주소가 가장 높은 주소를 가리킵니다.
즉, 스택 메모리의 주소 순서는 시스템의 아키텍처에 따라 결정되며, 32비트와 64비트 시스템에서는 서로 반대 방향입니다.

역순 설계의 이유

32비트와 64비트 시스템에서 스택 메모리의 주소 순서가 반대인 이유는, 이들 시스템의 메모리 주소 공간이 다르기 때문입니다.

32비트 시스템에서는 메모리 주소 공간이 32비트(4바이트)로 제한되어 있습니다. 따라서 스택 메모리의 bottom 주소는 높은 주소로 할당되고, top 주소는 낮은 주소로 할당됩니다. 이는 주소 공간을 가능한 한 효율적으로 사용하기 위한 선택이었습니다.

반면에, 64비트 시스템에서는 메모리 주소 공간이 64비트(8바이트)로 크게 확장되었습니다. 이에 따라 스택 메모리의 bottom 주소는 낮은 주소로 할당되고, top 주소는 높은 주소로 할당됩니다. 이는 64비트 시스템에서도 32비트 시스템과 마찬가지로 주소 공간을 효율적으로 사용하기 위한 선택입니다.

또한, 이러한 설계는 함수 호출 시에 스택 프레임(Stack Frame)을 생성하고 제거할 때 편리합니다. 스택 프레임은 함수가 호출될 때 함수의 지역 변수와 매개 변수를 저장하기 위해 스택 메모리에 할당되는 공간을 말합니다. 스택 프레임을 생성할 때는 bottom 주소가 감소하도록, 제거할 때는 bottom 주소가 증가하도록 구현하면 스택 프레임을 쉽게 관리할 수 있습니다.

32비트 시스템

C 언어에서 지역 변수는 스택 메모리에 할당됩니다. 스택 메모리는 LIFO(Last-In-First-Out) 구조로 되어 있어서 마지막으로 들어온 데이터가 먼저 처리됩니다.

32비트 시스템에서는 포인터와 int의 크기가 4byte로 동일하기 때문에 스택 메모리에 int 변수와 포인터 변수가 번갈아 가며 할당됩니다. 예를 들어, 함수 내부에서 지역 변수 a, b, c, d, e가 선언되면 스택 메모리에 다음과 같은 순서로 할당됩니다.

[stack top]
e
d
c
b
a
[stack bottom]

데이터와 주소 관계

32비트 프로그래밍에서 스택 메모리는 데이터가 쌓일수록 주소가 감소합니다. 스택 메모리는 LIFO(Last-In-First-Out) 구조를 가지기 때문에 가장 최근에 쌓인 데이터가 스택의 가장 위에 위치하게 됩니다. 이 때문에 스택의 주소는 데이터가 쌓일수록 감소합니다.

예를 들어, 다음과 같은 코드가 있다고 가정해보겠습니다.

void myFunction() {
    int a = 1;
    int b = 2;
    int c = 3;
}

위 코드에서 myFunction() 함수가 호출되면, 함수 내부에서 a, b, c 세 개의 지역 변수가 선언됩니다. 이 변수들은 스택 메모리에 차례대로 할당되며, 주소는 아래와 같이 감소합니다.

[stack top]
c (address: 0x0012)
b (address: 0x0010)
a (address: 0x000E)
[stack bottom]

64비트 시스템

하지만 64비트 시스템에서는 포인터 변수의 크기가 8바이트이고 int 변수의 크기는 여전히 4바이트입니다. 따라서 스택 메모리에 int 변수와 포인터 변수가 번갈아 가며 할당되면 스택 메모리의 공간 낭비가 발생합니다. 이를 방지하기 위해 컴파일러는 스택 메모리의 정렬을 위해 8의 배수 크기의 메모리 블록에 지역 변수를 할당합니다.
따라서 64비트 시스템에서는 지역 변수의 메모리 주소 할당 순서가 8의 배수로 정렬됩니다. 예를 들어, 함수 내부에서 지역 변수 a, b, c, d, e가 선언되면 스택 메모리에 다음과 같은 순서로 할당됩니다.

[stack top]
e
d
c
b
a
[padding]
[stack bottom]

따라서 64비트 시스템에서는 메모리 공간을 효율적으로 사용하기 위해 지역 변수들을 정렬하여 할당하는 것이 차이의 원인입니다.

데이터와 주소 관계

64비트 시스템에서는 주소 공간이 64비트이므로, 스택 포인터는 더 큰 주소 범위를 가질 수 있습니다. 이로 인해 64비트 프로그래밍에서는 스택 메모리가 주소가 증가하면서 할당됩니다.

void myFunction() {
    int a = 1;
    int b = 2;
    int c = 3;
}

위 코드에서 myFunction() 함수가 호출되면, 함수 내부에서 a, b, c 세 개의 지역 변수가 선언됩니다. 이 변수들은 스택 메모리에 차례대로 할당되며, 주소는 아래와 같이 증가합니다.

[stack top]
c (address: 0x7ffeecf02ffc)
b (address: 0x7ffeecf02ff8)
a (address: 0x7ffeecf02ff4)
[stack bottom]
profile
You matter, never give up

0개의 댓글