여러 의견으로 게시 한 질문을 해결하려면 (게시물을 수정해야한다고 생각합니다) :
내가 이해하지 못하는 것은 컴퓨터가 변수의 값을 읽고 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
a
ASCII 의 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
.
프로그램 : a
variable에 쓸 것 y
입니다.
프로그램 : 내용을 표시하고 싶다 y
(그리고 여기에서 계속됩니다)
당신이 아마 끊어지고있는 것은-메모리의 첫 번째 자리가 더 이상 없을 때 어떻게됩니까 x
? 또는 두 번째는 더 이상 없습니다 y
? 사람이 읽을 때 어떤 일이 발생 x
A와 char
또는 y
포인터로? 요컨대 나쁜 일이 일어납니다. 이러한 것 중 일부는 잘 정의 된 동작을 가지고 있으며 일부는 정의되지 않은 동작을 가지고 있습니다. 정의되지 않은 동작은 정확히 아무것도 아닙니다. 프로그램이나 운영 체제 충돌에 이르기까지 모든 일이 발생할 수 있습니다. 잘 정의 된 동작조차 악의적 일 수 있습니다. x
내 프로그램에 대한 포인터로 변경 하여 프로그램이 포인터로 사용하도록하면 프로그램이 내 프로그램을 시작하도록 할 수 있습니다. 이것은 정확히 해커가하는 일입니다. 컴파일러는 다음 int x
과 같이 사용하지 않도록 도와줍니다 .string
그리고 그 자연의 것들. 기계어 코드 자체는 유형을 인식하지 못하며 지시 사항에 지시 된 대로만 수행합니다. 또한 런타임에 발견되는 많은 양의 정보가 있습니다. 프로그램에서 사용할 수있는 메모리 바이트는 무엇입니까? x
첫 번째 바이트 또는 12 번째 바이트에서 시작 합니까 ?
그러나 실제로 이와 같은 프로그램을 작성하는 것이 얼마나 끔찍한 지 상상할 수 있습니다 (조립 언어로 가능). 당신은 당신의 변수를 '선언'에 의해 시작 - 당신은 자신이 그 바이트 1은 말할 x
바이트 2가, y
그리고 당신이 코드로드 및 저장하는 레지스터의 각 라인을 작성할 때, (인간)을 당신은 어느 쪽이 기억해야 x
하고 어떤 하나는 y
시스템이 모르기 때문에입니다. 그리고 당신은 (인간으로서) 어떤 유형 x
과 유형을 기억해야합니다 y
. 왜냐하면 시스템은 전혀 모릅니다.