
메모리구조
2진수와 16진수의 이해
진법 변환
스택 프레임과 스택 오버 플로우


2진법을 설명하기 앞서 10진법을 알아보자.
인간은 10개의 손가락을 각각의 객체로 인지하여 펴지거나 접힌 것을 세는 셈법을 주로 써왔기에 오래 전부터 10진법을 사용해 왔다.
우리가 일상 생활을 하며 사용하는 10진법은 10개의 숫자를 가지고 수를 표현하며,
10이 만들어질때 마다 자릿수가 하나씩 올라간다.
10진법을 계산하는 방법은 누구나 알고 있지만 256을 나눠서 생각해보자.

사람과 다르게 전자기기의 경우는 신호를 특정 순서로 그룹화 하여 인지하기에 해당 신호가 켜졌는지(1), 꺼졌는지(0)를 구별하기 때문에 2진법을 기반으로 발전하였다.
2진법은 0과 1이라는 두 개의 숫자만을 사용하여 수를 나타내는 진법을 말한다.
2진법도 10진법과 같은 방법으로 2가 만들어 질때마다 자릿수가 하나씩 올라간다.
1 = 0001
2 = 0010 (자릿수 상승)
3 = 0011
4 = 0100 (자릿수 상승)
5 = 0101
6 = 0110 (자릿수 상승)

2진법에서 1은 스위치에 불이 들어왔다는 것이다. 이러한 불이 들어온곳의 자리수를 더해주기만 하면 10진수로 표현할 수 있다.
계산은 위 그림처럼 불이 들어온 첫 번째(1x8) 와 네 번째(1x1)의 자리수 끼리만 더해주면 빠르게 계산할 수 있다. (8 + 1)
따라서 1001(2진수)을 10진수로 변환하면 9가 된다.

2진수를 사용하다 보면 수가 커질수록 자릿수가 많아지고 알아보기 힘들어진다.
따라서 16진수를 사용하여 더 간결하게 나타낸다.
16진수는 자릿수 하나가 0부터 15까지 표현할 수 있다.
하지만 우리가 흔히 사용하는 아라비아 숫자는 0부터 9까지 밖에 없기 때문에
나머지 10은 A, 11은 B, 12는 C, 13은 D, 14는 E, 15는 F로 로마자를 사용해 표현한다.
따라서 12는 16진수로 C가 되는거고, 15는 16진수로 F가 되는 형태이고 그 다음 16은 16진수로 10이 된다.
20진법도 아니고 10진법도 아닌 어중간한 16진법을 컴퓨터 분야에서 사용하는 이유는
16진수 자릿수 하나가 2^4(4bit)을 표현할 수 있기 때문이다.
특히 컴퓨터에서 사용하는 이유는 자릿수 2개를 사용하면 2^8을 표현할 수 있는데,
2^8은 곧 1바이트이다. 간단히 1바이트의 값을 2진법을 사용해서 0101 1111 식으로 표기할 게 아니라 그냥 16진법으로 0x5F라고 표기해 버리면 많이 축약할 수 있다.
게다가 훈련이 된 상황이라면 16진법의 숫자만 보고도 바로 2진법 수로 변환이 가능하기 때문에 상당히 유용한 표현 방법이다.
접두어 0x를 붙여서 0x10처럼 표기한다.
10진수 | 16진수 | 계산법
1 = 0x01 = (0 x 16¹) + (1 x 16⁰) 참고) 16⁰ = 1
2 = 0x02 = (0 x 16¹) + (2 x 16⁰)
...
10 = 0x0a = (0 x 16¹) + (10 x 16⁰)
11 = 0x0b = (0 x 16¹) + (11 x 16⁰)
...
15 = 0x0f = (0 x 16¹) + (15 x 16⁰)
16 = 0x10 = (1 x 16¹) + (0 x 16⁰)
17 = 0x11 = (1 x 16¹) + (1 x 16⁰)
...
25 = 0x19 = (1 x 16¹) + (9 x 16⁰)
26 = 0x1a = (1 x 16¹) + (10 x 16⁰)

RGB값을 표현할때 각 8bit씩 24bit(+Alpha값 8bit) = 32비트 트루컬러로 표현한다.
8bit는 16진수 두 자리로 표현 가능하니 색상 표현을 할때 16진수가 사용된다.

게임이나 어떤 프로그램을 다운로드 할 때 한 번쯤은 반드시 들어봤을 단어가 있습니다.
'32bit 운영체제 용', '64bit 운영체제 용'
또는 Windows 운영체제 사용자들 대다수가 한 번쯤을 봤을 x86(32비트) 또는 x64(64비트) 가 있죠.
이 둘의 차이점을 아주 간단하게 말하자면 비트의 너비(폭)이라고 보시면 됩니다. 비유하자면 고속도로에 32개의 차선이 있는데 이를 더 넓혀 64개의 차선으로 만든 것이죠. 직관적으로 말하자면 데이터 처리 단위라고 보시면 됩니다.
그리고 32개의 비트가 있다는 것은 0000 0000 0000 0000 0000 0000 0000 0000 부터 1111 1111 1111 1111 1111 1111 1111 1111 까지, 그러니까 232의 경우의 수를 갖고,
64개의 비트가 있다는 것은 264의 경우의 수를 갖는다는 것이죠.
이 둘의 차이는 생각보다 엄청나게 큽니다.
232 = 4,294,967,296 (약 43억)
264 = 18,446,744,073,709,551,616 (약 1844경)
64bit 운영체제가 데이터 처리 단위가 더 많다보니 당연히 CPU 처리도 고속화 되고, 새로운 명령어들도 만들 수 있죠. 그렇다보니 64bit 운영체제에서는 32bit프로그램을 돌릴 수가 있지만, 32bit에서는 64bit용 프로그램을 돌릴 수가 없는 것입니다.
64bit 는 8바이트이므로 하나의 주소가 8바이트 길이의 주소를 갖는다는 것을 알 수 있겠죠? 그리고 마찬가지로 264개. 즉, 18,446,744,073,709,551,616 개의 주소를 가리킬 수 있다는 의미고 이는 18,446,744,073,709,551,616 byte = 16EB(엑사바이트) = 16384PB(페타바이트) = 16777216TB(테라바이트) 까지 입니다.
(정확히는 16EiB = 16384PiB = 16777216TiB 이죠.)
한 마디로 이론적으로는 램을 16EB까지 설치 할 수 있다는 것이죠. (엑사바이트는 페타바이트의 1024배입니다.)

하지만 이 주소를 2진수로 표현하기에는 너무 길어 우리는 보통 편의상 16진수로 표현합니다.
32bit에서는 0x00000000 ~ 0xFFFFFFFF
64bit에서는 0x0000000000000000 ~ 0xFFFFFFFFFFFFFFFF
이렇게 말이죠.
8개의 비트를 하나로 묶어 1바이트(byte)라고 한다.
1바이트는 영문자 한 글자가 저장될 수 있는 메모리 크기이며 관리의 최소단위이다.
한글 한 글자를 저장하려면 2바이트가 필요하다.
4비트는 16가지(0 ~ 15), 8비트는 256가지(0 ~ 255), 16비트는 65,536가지(0 ~ 65,535)의 수를 표현할 수 있다.
2의 10제곱은 1024다. 2의 10제곱마다 용량의 단위가 변한다.

십진수로는 65, 컴퓨터에겐 영문 대문자 'A', 16진수로는 0x41
컴퓨터에는 숫자밖에 없는데 글자를 표현하고 싶어서 숫자 하나를 글자로 매핑하자고 약속을 하였는데 그것이 코드체계이다. 각자 독자적인 코드체계를 쓰다보니 규격이 필요해 졌고, ASCII 코드 체계가 등장했다.
