여러 의견으로 게시 한 질문을 해결하려면 (게시물을 수정해야한다고 생각합니다) :
내가 이해하지 못하는 것은 컴퓨터가 변수의 값을 읽고 10001과 같은 주소를 int 또는 char 인 경우 어떻게 알 수 있는지입니다. anyprog.exe라는 프로그램을 클릭한다고 상상해보십시오. 코드가 즉시 실행되기 시작합니다. 이 exe 파일에 변수가 또는 char로 저장되어 있는지에 대한 정보가 포함됩니까?
코드를 넣겠습니다. 다음과 같이 작성한다고 가정 해 봅시다.
int x = 4;
그리고 RAM에 저장되었다고 가정 해 봅시다.
0x00010004: 0x00000004
첫 번째 부분은 주소이고 두 번째 부분은 값입니다. 프로그램 (머신 코드로 실행)이 실행될 때 볼 수있는 0x00010004것은 모두 value 0x000000004입니다. 이 데이터의 유형을 '알지'않으며, 어떻게 '사용될'지 알지 못합니다.
그렇다면 프로그램이 올바른 일을 어떻게 파악합니까? 이 코드를 고려하십시오.
int x = 4;
x = x + 5;
우리는 여기에 읽고 쓸 수 있습니다. 프로그램 x이 메모리에서 읽을 때 메모리에서 찾습니다 0x00000004. 그리고 당신의 프로그램은 0x00000005그것에 추가 하는 것을 알고 있습니다. 그리고 프로그램이 이것이 유효한 연산임을 '알고'있는 이유는 컴파일러가 타입 안전을 통해 연산이 유효한지 확인하기 때문입니다. 귀하의 컴파일러는 이미 추가 할 수 있다는 것을 확인했습니다 4와 5함께. 따라서 이진 코드가 실행되면 (exe) 확인할 필요가 없습니다. 모든 것이 정상이라고 가정하고 각 단계를 맹목적으로 실행합니다 (사실은 정상이 아닌 나쁜 일이 발생합니다).
그것을 생각하는 또 다른 방법은 다음과 같습니다. 나는 당신 에게이 정보를 제공합니다 :
0x00000004: 0x12345678
이전과 같은 형식-왼쪽의 주소, 오른쪽의 값 어떤 유형의 값입니까? 이 시점에서 코드를 실행할 때 컴퓨터가하는 것처럼 그 값에 대한 많은 정보를 알게됩니다. 12743을 그 값에 더하라고 말하면 할 수 있습니다. 해당 작업의 영향이 전체 시스템에 어떤 영향을 줄지 모르지만 두 숫자를 추가하는 것이 실제로 잘하는 일이므로 할 수 있습니다. 그 값을 int? 반드시 그런 것은 아닙니다. 두 개의 32 비트 값과 더하기 연산자 만 있으면됩니다.
아마도 혼란의 일부는 데이터를 다시 가져 오는 것입니다. 우리가 가지고 있다면 :
char A = 'a';
컴퓨터 a가 콘솔 에 표시 되는 것을 어떻게 알 수 있습니까? 글쎄, 그것에 많은 단계가 있습니다. 첫 번째는 A메모리의 위치 로 이동하여 읽는 것입니다.
0x00000004: 0x00000061
aASCII 의 16 진수 값 은 0x61이므로 위의 메모리에서 볼 수 있습니다. 이제 기계 코드는 정수 값을 알고 있습니다. 정수 값을 문자로 변환하여 표시하는 방법을 어떻게 알 수 있습니까? 간단히 말해, 컴파일러는 전환을 수행하는 데 필요한 모든 단계를 수행했습니다. 그러나 컴퓨터 자체 (또는 프로그램 / exe)는 해당 데이터의 유형이 무엇인지 모릅니다. 즉, 32 비트 값이 무엇이든 될 수있다 - int, char(A)의 절반 double, 포인터 배열의 일부 (A)의 일부가 string, 명령의 일부 등
다음은 프로그램 (exe)과 컴퓨터 / 운영체제 간의 간단한 상호 작용입니다.
프로그램 : 시작하고 싶습니다. 20MB의 메모리가 필요합니다.
운영 체제 : 사용되지 않는 20MB의 사용 가능한 메모리를 찾아서 넘겨줍니다.
(중요한 사항은 20MB의 메모리를 반환 할 수 있다는 것입니다. 연속 할 필요조차 없습니다.이 시점에서 프로그램은 이제 OS와 통신하지 않고도 메모리 내에서 작동 할 수 있습니다)
프로그램 : 메모리의 첫 번째 스팟은 32 비트 정수 변수라고 가정하겠습니다 x.
(컴파일러는 다른 변수에 대한 액세스가 메모리의이 지점에 절대로 닿지 않도록합니다. 시스템에는 첫 번째 바이트가 가변적 x이거나 해당 변수 x가 정수라는 말이 없습니다. 비유 : 가방이 있습니다. 이 가방에 노란 색의 공만 넣을 것입니다. 나중에 가방에서 무언가를 꺼낼 때, 뭔가 파란색이나 큐브를 꺼내는 것이 충격적 일 것입니다. 프로그램은 이제 첫 번째 메모리 스팟이 변수 x이고 정수라고 가정합니다.이 바이트의 메모리에 다른 것이 쓰여지거나 다른 것으로 추정되는 경우 컴파일러는 이런 일이 발생하지 않도록합니다. 일어나지 않는다)
프로그램 : 이제 2가정하고있는 처음 4 바이트에 씁니다 x.
프로그램 :에 5를 추가하고 싶습니다 x.
프로그램 : 사용 가능한 다음 바이트가 char 변수라고 가정합니다 y.
프로그램 : avariable에 쓸 것 y입니다.
프로그램 : 내용을 표시하고 싶다 y
(그리고 여기에서 계속됩니다)
당신이 아마 끊어지고있는 것은-메모리의 첫 번째 자리가 더 이상 없을 때 어떻게됩니까 x? 또는 두 번째는 더 이상 없습니다 y? 사람이 읽을 때 어떤 일이 발생 xA와 char또는 y포인터로? 요컨대 나쁜 일이 일어납니다. 이러한 것 중 일부는 잘 정의 된 동작을 가지고 있으며 일부는 정의되지 않은 동작을 가지고 있습니다. 정의되지 않은 동작은 정확히 아무것도 아닙니다. 프로그램이나 운영 체제 충돌에 이르기까지 모든 일이 발생할 수 있습니다. 잘 정의 된 동작조차 악의적 일 수 있습니다. x내 프로그램에 대한 포인터로 변경 하여 프로그램이 포인터로 사용하도록하면 프로그램이 내 프로그램을 시작하도록 할 수 있습니다. 이것은 정확히 해커가하는 일입니다. 컴파일러는 다음 int x과 같이 사용하지 않도록 도와줍니다 .string그리고 그 자연의 것들. 기계어 코드 자체는 유형을 인식하지 못하며 지시 사항에 지시 된 대로만 수행합니다. 또한 런타임에 발견되는 많은 양의 정보가 있습니다. 프로그램에서 사용할 수있는 메모리 바이트는 무엇입니까? x첫 번째 바이트 또는 12 번째 바이트에서 시작 합니까 ?
그러나 실제로 이와 같은 프로그램을 작성하는 것이 얼마나 끔찍한 지 상상할 수 있습니다 (조립 언어로 가능). 당신은 당신의 변수를 '선언'에 의해 시작 - 당신은 자신이 그 바이트 1은 말할 x바이트 2가, y그리고 당신이 코드로드 및 저장하는 레지스터의 각 라인을 작성할 때, (인간)을 당신은 어느 쪽이 기억해야 x하고 어떤 하나는 y시스템이 모르기 때문에입니다. 그리고 당신은 (인간으로서) 어떤 유형 x과 유형을 기억해야합니다 y. 왜냐하면 시스템은 전혀 모릅니다.