혼공컴구 책을 쭉 보니까 책 앞부분이 데이터와 명령어를 다루고 있다. 그런데 데이터는 이진수로 숫자와 문자를 표기하는 방법에 대해서 나타내고 있길래.. 이건 패스 이 부분은
https://dev-dx2d2y-log.tistory.com/77
[CS] 자바의 정석 독서 #3 - float, double, 부동소수점, 그리고 오차
https://www.youtube.com/watch?v=-GsrYvZoAdA예전에 이런 글을 본 적이 있다. 0.1 + 1.1 != 1.2 라니그 때 궁금해져서 영상을 보긴했는데 부동소수점 개념이 잘 이해되지 않아서 그냥 그런가보다하고 넘어갔다.
dev-dx2d2y-log.tistory.com
이전에 한 번 다뤘기 때문이기도하다. 십진수-이진수 변환이야 그냥 계산하면 되는 편이고 부동소수점 정도만 좀 연산방식이 다르다는 것, 그리고 문자는 문자를 숫자에 대응시킨 아스키 코드를 사용한다 정도로만 이해하면 되겠다. 이 다음 명령어도 초반 내용은 인터프리터와 컴파일러에 대한 내용을 다루고 있기 때문에 패스. 03-2부터 읽을 것인데 04장부터 운체 내용인데 컴구가 이렇게 끝난다고...?
명령어의 구조
나중에 어셈 책도 읽을 것이지만 컴파일 언어는 명령어를 기계어로 컴파일하고, 이 컴파일된 기계어는 각각 어셈블리어의 명령어와 대응된다. 가령 0101 0101은 어셈블리어로 push rbp 정도가 되는 것이다. 나중에 성능 튜닝 등의 목적을 위해서 저수준 프로그래밍을 진행해야할 때가 있는데 그럴 때 주로 쓰인다고.
암튼 그래서 명령어는 대상이 저장된 위치과 연산으로 이루어져있다. 가령 "메모리 주소 xx에 저장된 값과 메모리 주소 yy에 저장된 값을 더하라"라고하면, xx와 yy가 대상이 저장된 위치, 더하라가 연산이다.
명령어는 연산코드와 오퍼랜드로 이루어져있다.
위에서의 연산, 즉 명령어가 수행할 연산을 연산코드(Operation code), 위에서의 대상, 즉 연산에 사용할 데이터가 저장된 위치를 오퍼랜드(Operand)라고 한다.

그래서 대충 이렇게 나타낼 수 있고

이렇게 명령어는 연산코드와 오퍼랜드를 가진다.
연산코드가 담기는 영역을 연산코드필드, 오퍼랜드가 담기는 영역을 오퍼팬드 필드라고 한다. 즉, 명령어가 저장될 때에는 연산코드와 오퍼랜드가 필드로 나뉘어져서 같이 저장된다.
어셈블리어를 봐도
push rpb
mov rbp, rsp
mov DWORD PTR [rbp-4], 1
이런식으로 연산코드와 오퍼랜드로 나뉘는 것을 알 수 있다. 기계어는 어셈블리어를 기계어에 대응시켜서 저장시키므로 메모리 영역에 저장되는 명령어도 이 연산코드 - 오퍼랜드 형태로 저장된다,
오퍼랜드
오퍼랜드는 '연산에 사용할 데이터가 저장된 위치' (또는 연산에 사용할 데이터)를 나타낸다. 보통 연산의 대상이 되는 숫자나 문자, 또는 메모리나 레지스터의 주소를 담는 편이다. 많은 경우에는 데이터가 저장된 위치를 나타내는 편이다. 그래서 오퍼랜드 필드를 주소 필드라고 부르기도한다고.
오퍼랜드는 명령어에서 여러 개를 가질 수도 있고, 가지지 않을 수도 있다. 없으면 0-주소 명령어, 1개면 1-주소 명령어 ... 3개면 3-주소 명령어 이렇게 부른다.
연산코드
연산코드는 오퍼랜드(들)를 가지고 어떤 연산을 수행해야할 지를 적어놓는다.
가장 기본적인 연산코드는
데이터 전송
MOVE(옮기기) / STORE(저장) / LOAD(메모리에서 CPU로 데이터 전송) / PUSH / POP (스택의 그거 맞다.)
산술논리연산
ADD / SUBTRACT / MULTIPLY / DIVIDE (사칙연산)
INCREMENT / DECREMENT (오퍼랜드에서 1을 더하거나 빼기)
AND / OR / NOT
COMPARE (두 숫자나 참거짓을 비교)
제어 흐름 변경
JUMP (특정 주소로 실행순서 옮기기)
CONDITIONAL JUMP (조건에 부합할 때 JUMP)
HALT (실행멈춤)
CALL (JUMP하되 명령어 수행 후 되돌아올 주소를 지정하기)
RETURN (CALL을 호출할 때 저장했던 주소로 돌아가기)
입출력 제어
READ (특정 입출력 장치로부터 데이터 읽기)
WRITE (특정 입출력 장치로부터 데이터 쓰기)
START IO (입출력장치 시작)
TEST IO (입출력장치의 상태확인)
가 있다. 연산코드의 수는 많지만, 저 넷이 가장 기본적으로 많이 쓰인다. 명령어를 다 외울 필요는 없고, 저게 어셈블리어에 해당한다. 나중에 어셈 배우면 외울듯?
주소 지정 방식
앞서 오퍼랜드에는 주로 데이터가 저장된 위치를 담는다고했다. 이는 명령어 길이 때문인데, 명령어의 길이가 고정되어있다면 0-주소 명령어에서 3-주소 명령어로 갈수록 오퍼랜드 한 개의 크기는 줄어든다.
명령어의 크기가 16바이트, 연산코드 필드가 4바이트에 3-주소 명령어라면 오퍼랜드 필드 12바이트를 오퍼랜드 3개가 4바이트씩 나눠갖는다. 그럼 표현할 수 있는 숫자는 2^4 개인 16개 밖에 없다. 음수도 표현할거면 -8부터 7까지.
따라서 오퍼랜드에는 연산에 수행될 대상을 그대로 저장하는 것이 아니라, 수행될 대상이 저장된 메모리 주소를 적어놓는 것을 주로 사용한다. 같은 상황에서 오퍼랜드 필드에 주소를 저장하면 오퍼랜드 필드 한 개에 저장할 수 있는 데이터의 수는 하나의 메모리 주소에 저장할 수 있는 공간만큼 커진다. 가령 16바이트 메모리를 사용한다면, 메모리의 주소는 16개로 밖에 표현할 수 없겠지만 각 메모리에 2^16 자리수의 수를 저장할 수 있으므로 더욱 원활한 수 표현이 가능하다. 레지스터도 마찬가지. 레지스터에 데이터를 저장할 때에도 레지스터가 저장할 수 있는 정보의 크기만큼 정보를 저장할 수 있다.
이처럼 오퍼랜드에서 연산에 사용할 데이터가 저장된 위치를 유효주소(Effective address)라고 칭한다.
그리고, 오퍼랜드 필드에 데이터가 저장된 위치를 명시할 때 연산에 사용될 데이터를 찾는 방법을 주소 지정 방식(Addressing mode)라고 칭한다. 그리고 이 방식은 여러 개가 있다.
즉시 주소 지정 방식
Immediate addressing mode
가장 간단한 형태의 방식으로, 데이터를 오퍼랜드 필드에 직접 명시한다. 앞서 봤듯이, 16바이트 명령어 크기에 3-주소 명령어라면 값을 16개 밖에 표현하지 못하는등 표현할 수 있는 값의 크기가 작아지지만, 데이터를 메모리에서 찾는 과정이 없기 때문에 단순하고 빠르다.
직접 주소 지정 방식
Direct addressing mode
유효 주소를 오퍼랜드 필드에 직접 명시한다. 앞서 봤듯이, 즉시 주소 지정 방식보다는 데이터를 더 많이 가리킬 수 있게되었지만, 여전히 유효 주소의 값에 한계가 있다.
간접 주소 지정 방식
Indirect addressing mode
유효주소의 주소를 오퍼랜드 필드에 명시한다. 즉, 유효주소를 저장하고, 그 유효주소를 메모리에 다시 저장하고, 오퍼랜드 필드에는 유효주소의 값이 저장된 주소를 명시하는 것이다. 16바이트 3-주소 오퍼랜드에서 16개의 주소를 표현할 수 있고, 각 주소는 2^16 개의 값을 저장할 수 있었다.

간접 주소 지정방식은 앞선 16바이트 3-주소 명령어 체계에서 유효주소의 주소로 16개의 값을, 유효주소로는 2^16개의 값을 사용하고 연산에 사용할 데이터로 2^16개를 나타낼 수 있다. 즉, 직접 주소 지정 방식과 표현할 수 있는 데이터의 양은 같지만, 간접 주소 지정 방식에서는 데이터를 저장할 주소의 값을 여러 개 사용할 수 있다. 2^16개.
다만 데이터를 찾기 위해서 두 번씩 메모리를 뒤져야하므로 일반적으로 느린 편이다.
레지스터 주소 지정 방식
Register addressing mode
레지스터는 CPU 내부에 있는 저장공간으로, 그래서 메모리보다 데이터를 가져오는 것이 더 빠르다. 그래서 레지스터에 데이터를 저장하는 경우도 있다.
레지스터 주소 역시 유효주소를 직접 오퍼랜드에 담을 수 있다. 다만 이 방식은 직접 주소 지정 방식의 단점과 문제점을 공유한다.
레지스터 간접 주소 지정 방식
Register indirect addressing mode
그래서 레지스터도 간접 주소 지정 방식을 사용할 수 있으나, CPU 내의 레지스터는 그 개수가 적기 때문에 레지스터만으로 간접 주소 지정을 하지는 않는 편이다. 16바이트 3-주소 명령어에 16개의 레지스터를 가진 PC가 있다면 간접 주소 지정 방식을 사용하는 것보다는 그냥 오퍼랜드 한 개로 레지스터 번호를 표기하는게 더 싸게 먹히기 때문.
그래서 주로 메모리를 사용한다.
메모리에 실제 데이터를 저장하고, 그 유효주소를 레지스터에 저장한 다음에, 오퍼랜드에는 어느 레지스터에 유효주소가 저장되었는지를 기재한다.
위에서 메모리보다 레지스터에서 데이터를 가져오는 것이 더 빠르다고했으므로 이 방식은 값을 많이 저장할 수도 있고, 주소도 많이 저장할 수 있으면서도 간접 주소 지정 방식보다 빠르다.
이외에도 여러 레지스터 주소 지정 방식이 있다. 그러나 이는 레지스터를 알아야하므로 우선은 패스
우선은 컴구에서 중요한 두 가지 중 하나인 "컴퓨터가 이해할 수 있는 것"에 대해서 알아보았다. 각각 데이터와 명령어인데, 데이터 부분은 그냥 알고 있어서 패스했고 명령어 부분만 명령어가 어떻게 저장되는지, 그리고 어떤 구조를 가지는지 등에 대해서 알아보았다.
이후로는 컴구의 중요한 다른 요소인 "컴퓨터를 이루는 핵심 부품"에 대해서 알아보고, 그래서 우선은 이 다음부터 CPU에 대해서 알아볼 예정이다. 04장부터 운체인줄 알았는데 09장부터 운체였다. 컴구와 운체가 반반씩 내용을 차지하는 듯. 우선은 같이 배우다가 분리시킬 생각이다.
어떤 선배가 컴구 배우고 운체 배우라고 했는데 (반대일 수도 있음) 왜인지 알 것 같기도하고..
'CS > 컴퓨터구조' 카테고리의 다른 글
| [컴퓨터구조] OOO, OoOE, 토마슬로 알고리즘을 통한 비순차적 명령어 처리 + 혼공컴구 독서 #6 - CPU 성능향상 (1) | 2026.01.25 |
|---|---|
| [컴퓨터구조] 혼공컴구 독서 #5 - 명령어 사이클과 인터럽트 (0) | 2026.01.23 |
| [컴퓨터구조] 혼공컴구 독서 #4 - CPU 레지스터 (0) | 2026.01.20 |
| [컴퓨터구조] 혼공컴구 독서 #3 - CPU - ALU, 플래그, 제어장치 (0) | 2026.01.17 |
| [컴퓨터구조] 혼공컴구 독서 #1 - 컴퓨터구조 개관 및 기초 (1) | 2026.01.14 |
