변수 이름은 C의 메모리에 어떻게 저장됩니까?
C에 다음과 같은 변수가 있다고 가정합니다.variable_name
예를 들어 다음 위치에 있다고 칩니다.0xaaaaaaaa
그 메모리 주소에는, 123 의 정수가 있습니다.다른 말로 하자면variable_name
에는 123이 포함되어 있습니다.
"라는 표현에 대한 해명을 구하고 있습니다.variable_name
설치 장소:0xaaaaaaaa
". 컴파일러는 문자열 "variable_name"이 특정 메모리 주소와 관련되어 있음을 어떻게 인식합니까?문자열 "variable_name"이 메모리 어딘가에 저장되어 있습니까?컴파일러는 단지 다음 명령어를 대체합니까?variable_name
위해서0xaaaaaaaa
그걸 볼 때마다, 만약 볼 수 있다면, 그걸 대체하기 위해서 기억을 사용해야 하지 않을까요?
컴파일러 실행 후 변수 이름은 더 이상 존재하지 않습니다(공유 라이브러리에서 내보낸 글로벌이나 디버깅 기호와 같은 특수한 경우는 제외).컴파일 전체의 목적은 소스 코드로 나타나는 심볼 이름과 알고리즘을 네이티브 머신 명령으로 변환하는 것입니다.네, 만약 당신이 글로벌하게variable_name
컴파일러와 링커는 이 파일을 다음 위치에 배치합니다.0xaaaaaaaa
코드 내에서 사용되는 모든 위치에 해당 주소를 통해 액세스할 수 있습니다.
문자 그대로의 질문에 답하려면:
컴파일러는 문자열 "variable_name"이 특정 메모리 주소와 관련되어 있음을 어떻게 인식합니까?
툴 체인(컴파일러와 링커)은 함께 동작하여 변수의 메모리 위치를 할당합니다.모든 참조를 추적하는 것은 컴파일러의 역할이며 링커는 나중에 올바른 주소를 입력합니다.
문자열입니까?
"variable_name"
기억 속 어딘가에 저장돼 있을까?
컴파일러가 실행되고 있는 동안만.
컴파일러는 단지 다음 명령어를 대체합니까?
variable_name
위해서0xaaaaaaaa
그걸 볼 때마다, 만약 볼 수 있다면, 그걸 대체하기 위해서 기억을 사용해야 하지 않을까요?
네, 거의 그런 일이 벌어지죠 링커와 함께 하는 2단계 작업이라는 것만 빼면요네, 메모리를 사용하지만 컴파일러의 메모리이지 실행 시 프로그램에는 아무것도 없습니다.
예를 들면 이해에 도움이 될 수 있습니다.이 프로그램을 사용해 보겠습니다.
int x = 12;
int main(void)
{
return x;
}
꽤 간단하죠?이 프로그램을 컴파일하여 디스어셈블리를 살펴보겠습니다.
$ cc -Wall -Werror -Wextra -O3 example.c -o example
$ otool -tV example
example:
(__TEXT,__text) section
_main:
0000000100000f60 pushq %rbp
0000000100000f61 movq %rsp,%rbp
0000000100000f64 movl 0x00000096(%rip),%eax
0000000100000f6a popq %rbp
0000000100000f6b ret
저것 좀 봐주세요movl
라인이요? 글로벌 변수를 잡고 있습니다(이 경우 명령 포인터의 상대적인 방식으로).에 대해서는 더 이상 언급하지 않는다.x
.
이제 좀 더 복잡하게 로컬 변수를 추가해 보겠습니다.
int x = 12;
int main(void)
{
volatile int y = 4;
return x + y;
}
이 프로그램의 분해는 다음과 같습니다.
(__TEXT,__text) section
_main:
0000000100000f60 pushq %rbp
0000000100000f61 movq %rsp,%rbp
0000000100000f64 movl $0x00000004,0xfc(%rbp)
0000000100000f6b movl 0x0000008f(%rip),%eax
0000000100000f71 addl 0xfc(%rbp),%eax
0000000100000f74 popq %rbp
0000000100000f75 ret
이제 두 개가 있다movl
설명서와addl
설명.보시는 것처럼 첫 번째는movl
초기화 중y
스택(베이스 포인터 - 4)에 배치됩니다.그럼 다음번에는movl
글로벌화x
등록부에.eax
, 및addl
추가하다y
그 값까지.하지만 보다시피, 문자 그대로는x
그리고.y
끈은 더 이상 존재하지 않아요프로그래머인 당신에게 편리했던 것들이지만, 컴퓨터는 실행 시 전혀 신경 쓰지 않습니다.
모든 변수는 컴파일러에 의해 대체됩니다.처음에 참조로 대체되고 나중에 링커는 참조 대신 주소를 배치합니다.
바꿔 말하면.컴파일러가 실행되자마자 변수 이름을 사용할 수 없습니다.
C 컴파일러는 먼저 변수 이름과 변수 이름이 메모리에 있는 위치 사이의 관계를 저장하는 기호 테이블을 만듭니다.컴파일 시 이 테이블을 사용하여 다른 사용자가 설명한 바와 같이 변수의 모든 인스턴스를 특정 메모리 위치로 바꿉니다.위키피디아 페이지에서 더 많은 것을 찾을 수 있습니다.
이를 구현 상세라고 합니다.제가 지금까지 사용해 본 컴파일러는 모두 해당되지만 반드시 해당될 필요는 없습니다.C 컴파일러는 모든 변수를 해시테이블에 넣고 런타임(또는 그와 비슷한 것)에 검색할 수 있습니다.실제로 초기 JavaScript 인터프리터는 바로 그렇게 했습니다(현재는 Just-In-TIME 컴파일러는 훨씬 더 원시적인 결과를 낳습니다).
특히 VC++, GCC, LLVM과 같은 일반적인 컴파일러의 경우: 컴파일러는 일반적으로 메모리 내의 위치에 변수를 할당합니다.글로벌 또는 스태틱스코프의 변수는 프로그램 실행 중에 변경되지 않는 고정 주소를 얻는 반면 함수 내의 변수는 스택주소, 즉 함수가 호출될 때마다 변경되는 현재 스택포인터에 상대적인 주소를 가져옵니다.(이는 지나치게 단순합니다.)스택 주소는 함수가 반환되는 즉시 비활성화되지만 실질적으로 사용할 오버헤드가 0이라는 이점이 있습니다.
변수에 주소가 할당되면 변수 이름은 더 이상 필요하지 않으므로 폐기됩니다.이름의 종류에 따라 이름은 전처리 시(매크로 이름의 경우), 컴파일 시(스태틱 및 로컬 변수/함수의 경우) 및 링크 시간(글로벌 변수/함수의 경우)에 폐기될 수 있습니다.기호를 내보내는 경우(다른 프로그램이 액세스할 수 있도록 표시됨), 보통 이름은 메모리와 디스크 공간을 차지하는 "심볼 테이블" 어딘가에 남아 있습니다.
컴파일러가 variable_name을 볼 때마다 0xaaaaaaaaaaaaaaaaaaaaaaaaaa
네.
그렇다면 메모리를 사용해서 대체해야 하지 않을까요?
네, 하지만 컴파일러가 코드를 컴파일한 후에 왜 메모리에 신경을 쓰죠?
언급URL : https://stackoverflow.com/questions/14612314/how-are-variable-names-stored-in-memory-in-c
'programing' 카테고리의 다른 글
루프를 만들 때 Vue Js에서 특정 번호 범위를 표시하는 방법은 무엇입니까? (0) | 2022.07.07 |
---|---|
@PostConstruct를 사용하는 이유 (0) | 2022.07.07 |
Vue.js 또는 Nuxt.js 일원화된 애플리케이션 구성 (0) | 2022.07.04 |
Mac OS X 및 여러 Java 버전 (0) | 2022.07.04 |
Vue Router에서 404 응답을 얻는 방법 (0) | 2022.07.04 |