이번주 미션은 CPU와 프로세스 메모리의 작동 원리에 대해 공부하고
해당 원리를 프로그램으로 구현하는 것이었다.
CS 지식이 거의 백지인 상태로 짧은 시간 안에 원리를 공부하고
구현하는 것이 쉽지는 않은 것 같다.
거기에다 CS 기간에는 멘토가 있는 것이 아니라 주제가 던져지면
그룹원들끼리 공부한 내용이나 모르는 부분에 대해 토론하는 형식으로 진행되기 때문에
애매한 부분은 알맞게 인지하는 것인지 아닌지 모르는 상태에서 넘어갈 때도 있었다.
개발자는 평생 공부해야 하기 때문에 스스로 주도적으록 공부하는 습관이 좋다고 수도 없이 들었다.
필자 역시 동의하는 부분이다.
그런데 방향을 헤매고 있고 심지어 그 방향이 잘못되었다는 것을 모르고 있을 때
잡아주는 사람도 필요한 것 같다.
아직 2주밖에 진행되지 않았지만, 모르는 주제 뒤에 더 어려운 주제가 계속 던져지고
공부한 내용을 맞게 인지하고 있는지, 코드는 어떤지 피드백이 없다보니
필자도, 같이 공부했던 그룹원도 조금 지친? 모습이 보였다.
스스로의 동기부여가 필요한 때인 것 같다.
"천리 길도 한 걸음부터"라고
어렵고 혼란스럽더라도 스스로를 믿고 하나씩 쌓아가다 보면 언젠가 희미한 방향이라도 보일 것이라고
지식을 어느정도 이해한다고 생각해서 구현을 시작했는데 CPU에 대해 완벽히 이해하지 못하니
코딩도 하다가 막혔다.
미션 당 이틀밖에 시간이 주어지지 않기 때문에 지식 습득, 프로그램 구현 둘 다 어정쩡하게 한 것 같다.
시간은 한정적인데 공부해야만 하는 지식 부채가 쌓여만가는 기분이다.
프로그램 구현도 결국 원리를 더 잘 이해하기 위한 과정이니
3주차에는 공부 방향을 지식 습득을 최우선으로 잡아보려 한다.
미션에 대해 정리한 상세 내용은 아래에 적어두었다.
0x0000b MOV R4, 0x00A0
0x0010b MOV R5, 0x0002
0x0020b LOAD R1, R4, R5
0x0030b ADD R2, R1, #4
0x0040b SUB R3, R1, R2
0x0050b STORE R3, R4, #4
공부한 내용은 블로그에 정리해두었다.
명령어 형식
|Instruction|4bit|3bit|3bit|3bit|3bit|설명|
|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
|LOAD|0001|dst.Reg|base.Reg|000|offset.Reg|(base. Reg + offset. Reg) 주소 메모리 값을 읽어서 dst. Reg로 로드한다.|
(각 Register는 3bit로 R1부터 R7까지 명시할 수 있다.)
명령어 비트코드 예시
[LOAD, R1, R2, R3] => [0001 001 010 000 011]
CPU 요구사항
메소드 요구사항
base = memory.init(1024, 1024)
memory.setSize("short", 4)
memory.setSize("int", 8)
memory.setSize("string", 16)
arrayPointer = memory.malloc("int", 4)
shortPointer = memory.malloc("short", 5)
print(heapdump())
call("foo", 2)
string1 = memory.malloc("crong", 1)
print(callstack())
call("bar", 1)
string2 = memory.malloc("jk", 2)
returnFrom("bar")
free(string1)
print(heapdump())
free(string2)
print(callstack())
garbageCollect()
print(heapdump())
reset()
print(heapdump())
CS 과정이라 당연하게도 CS 용어가 많이 나온다.
예를 들면 "메모리 주소"가 정말 많이 언급된다.
그래서 프로그램 구현을 위해 Java
로 구현하려면 메모리 주소를 어떻게 확인하고 다룰지 막막한데,
"메모리 주소"가 있다고 가정하고 구현하는 것이 좋을 것 같다.
이게 무슨 말이냐면,
메모리에 데이터 크기가 4바이트인 것인 int 타입 age
가 있고 해당 자료의 기본 주소(base address)와 포인터 주소를 확인해야 한다면
실제 메모리 주소를 다루는 것이 아니라 인덱스로 다루는 것이다.
예시는 다음과 같다.
List<Integer> memory // 자료를 저장하는 메모리 역할
void add() {
int baseAddress = memory.size(); // age가 시작하는 위치
for(int i = 0; i < 32; i++) { // 자료 크기만큼 데이터 저장
memory.add(age);
}
int pointer = memory.size() + age.size(); // 기본주소에서 떨어져 있는 만큼의 위치(= 포인터 주소)
}
필자가 말하는 것이 정답은 아니지만, 구현부터 막막한 분이 계신다면, 이 글이 도움이 되었음 좋겠다.
메모리 객체 구현
Stack Pointer
변수로 어디까지 쌓였는지 확인하는 기능함수 구현
init(stackSize, heapSize)
setSize(type, length)
malloc(type, count)
free(pointer)
call(name, paramCount)
returnFrom(name)
usage()
callstack()
heapdump
garbageCollect()
reset()