You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: 8-functions/README.md
+81-1Lines changed: 81 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -36,4 +36,84 @@ int main()
36
36
7. 4로 이동합니다.
37
37
```
38
38
39
-
이렇게 해석될 수 있습니다.
39
+
이렇게 해석될 수 있습니다.
40
+
41
+
## 프로그램 카운터(program counter)
42
+
43
+
지금까지 배운 컴퓨터의 구조를 정리해보겠습니다. RAM과 레지스터, 연산장치가 있습니다. 연산장치는 주어진 프로그램에 따라 RAM이나 레지스터에서 값을 넣고 빼고 연산합니다. 근데 그럼 프로그램은 어디에 있을까요? 프로그램도 일종의 정보인만큼 프로그램을 저장할 메모리가 필요해보입니다.
44
+
45
+
우리가 쓰는 컴퓨터는 프로그램도 RAM에 저장합니다. [1장](../1-prepare-development-environment)에서 컴파일러는 프로그램이 실행되기 전에 코드를 모두 읽고 번역한다고 했었습니다. 컴파일러가 코드를 번역한 결과는 정수의 배열 형태로 된 프로그램입니다. 그 프로그램을 실행하면 RAM에 그 프로그램이 전부 복사되게 되고, 그럼 연산장치가 RAM에 있는 배열 형태로 된 프로그램을 한 원소씩 읽어 실행할 수 있게 됩니다. 위 예제를 예로 들면, 저 프로그램이 `{ 0x48, 0x8D, 0x54, 0x24, 0x20, 0x48, 0x8D, 0x0D, 0x3F, 0x11, 0x00, 0x00, 0xE8, 0x7A, 0xFF, ... }` 라는 배열이 되어 RAM 어딘가에 존재하게 됩니다. 이 정수들은 무작위적인 숫자가 아니라, 별도의 변환과정 없이 연산장치의 회로가 인식할 수 있는 숫자들입니다. 이 숫자들의 규칙을 `기계어(machine code)`라고 합니다.
46
+
47
+
연산장치는 기계어 코드를 RAM에서 읽기 위해, 다음에 읽을 기계어 코드가 어디있는지 알아야 합니다. 연산장치는 다음에 읽을 기계어 코드가 저장된 공간의 주소도 레지스터에 저장하는데, 이 역할을 하는 레지스터를 프로그램 카운터라고 합니다.
48
+
49
+
프로그램 카운터는 기본적으로 증가하기만 합니다.
50
+
51
+
```c
52
+
intmain()
53
+
{
54
+
int i = 5;
55
+
int j = 6;
56
+
int k = i + j;
57
+
}
58
+
```
59
+
60
+
이 프로그램이 어떻게 실행되나요? 먼저 `int i = 5;`가 실행되고, `int j = 6;`이 실행되고, 그리고 `int k = i + j;`가 실행됩니다. 이 코드가 기계어로 변환되면, `int k = i + j;`에 해당되는 정수들이 `int i = 5;`나 `int j = 6;`에 해당되는 정수보다 상대적으로 뒤에 있을 것입니다. 그래서 프로그램 카운터를 증가시키는 것이 다음 문장을 실행하는 결과를 냅니다. 위 예제를 사람들이 하는 말에 가깝게 쓰면,
61
+
62
+
```
63
+
프로그램이 시작했을 때,
64
+
1. (적당한 공간을 i라고 이름짓고) i에 5를 넣습니다.
65
+
2. (적당한 공간을 j라고 이름짓고) j에 6을 넣습니다.
66
+
3. (적당한 공간을 k라고 이름짓고) k에 i와 j 각각이 갖고 있는 값을 더한 결과를 넣습니다.
67
+
```
68
+
69
+
프로그램 카운터가 1, 2, 3(에 대응하는 메모리 주소)으로 변화해 간다는 사실을 알 수 있습니다.
70
+
71
+
이 프로그램 카운터는 특정한 문장으로 값을 변경하는 것이 가능합니다. [7장](../7-control-flow)에서 다양한 제어 흐름 문장들에 대해 배웠는데요, if문을 예로 들겠습니다.
72
+
73
+
```c
74
+
#include<stdio.h>
75
+
76
+
intmain()
77
+
{
78
+
int i; scanf("%d", &i);
79
+
80
+
if (i < 5)
81
+
printf("%d", i + 10);
82
+
else
83
+
printf("%d", i);
84
+
}
85
+
```
86
+
```
87
+
프로그램이 시작했을 때,
88
+
1. (적당한 공간을 i라고 이름짓고) i라는 이름의 공간에 사용자의 입력을 넣습니다.
89
+
2. i < 5의 결과가 거짓이라면 5로 이동합니다.
90
+
3. i + 10을 출력합니다.
91
+
4. 6으로 이동합니다.
92
+
5. i를 출력합니다.
93
+
6.
94
+
```
95
+
96
+
사용자의 입력이 `14`라고 가정해보겠습니다. 그럼 프로그램 카운터는 기본적으로 1씩 증가합니다. 그런데, 2번에서 `i < 5`가 거짓이기 때문에 프로그램 카운터가 5로 바뀝니다. 그래서 이 경우 프로그램 카운터가 가지고 있는 값은 1, 2, 5, 6으로 변화해 간다는 사실을 알 수 있습니다. 반대로 사용자의 입력이 `3`이라면 프로그램 카운터 속 숫자는 1, 2, 3, 4, 6으로 변화해 간다는 사실을 알 수 있습니다.
97
+
98
+
for문에 대해서도 동일한 분석이 가능합니다.
99
+
100
+
```c
101
+
#include<stdio.h>
102
+
103
+
intmain()
104
+
{
105
+
for (int i = 1; i <= 5; ++i)
106
+
printf("%d ", i);
107
+
}
108
+
```
109
+
```
110
+
프로그램이 시작했을 때,
111
+
1. ebx에 1을 넣습니다.
112
+
2. ebx <= 5가 거짓이라면 6으로 이동합니다.
113
+
3. ebx에 들어있는 값을 출력합니다.
114
+
4. ebx의 값을 1 증가시킵니다.
115
+
5. 2로 이동합니다.
116
+
6.
117
+
```
118
+
119
+
그럼 이 프로그램의 경우 프로그램 카운터가 1, 2, 3, 4, 5, 2, 3, 4, 5, ..., 3, 4, 5, 2, 6으로 변화해 간다는 사실을 알 수 있습니다.
0 commit comments