일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- Comparator
- 메뉴 리뉴얼
- Comparable
- 요세푸스
- 오블완
- 고정소수점
- sw expert academy
- Call-by-Value
- 표 편집
- 조합
- 순열
- java
- 괄호 회전하기
- 티스토리챌린지
- 코테
- 도둑질
- 구현
- 베스트 앨범
- 다단계 칫솔 판매
- 토마토
- swea
- 데이터
- 자바
- 프로그래머스
- 백준
- 컴퓨터구조
- 운영 체제
- 컴퓨터 구조
- 기능 개발
- 부동소수점
- Today
- Total
감자는 아직 꿈을 꾼다.
[컴퓨터 구조] 3. 명령어 본문
< 목 차 >
1. 소스 코드와 명령어
2. 명령어의 구조
1. 소스 코드와 명령어
컴퓨터는 명령어를 처리하는 기계이고, 2장의 데이터에서 봤던 것처럼, 0과 1로 이루어진 정보만 이해할 수있습니다.
그런데 우리는 소스코드를 0과1로 작성하지 않습니다.
우리가 작성한 소스코드가 컴퓨터 내부에서 명령어로 변환 되는 것이죠
✏️고급 언어, 저급 언어
High Level에서 사람의 입장에서 컴퓨터에게 명령을 내리기위한 언어가 고급 언어입니다.
컴퓨터가 직접 이해하고 실행하는 언어가 저급언어이고,
저급언어는 명령어로 이루워져있고, 고급언어는 무조건 저급언어로 변환이 되어야 컴퓨터가 실행 할 수있습니다.
저급언어는 기계어와 어셈블리어 두 가지 종류가 있고, 기계어는 사람이 보면 단순히 0과 1의 배열일 뿐입니다.
이해가 가질 않죠, 그래서 어셈블리어가 등장한 것입니다.
어셈블리어는 사람이 기계어를 읽기 쉽게 변역한 저급언어입니다.
이것도 사람이 보기 힘들수 있습니다.
그래서 고급언어로 저희가 개발하는 것입니다.
하지만 보안이나 시스템 프로그래밍 쪽으로 개발하시는 분들은 소스코드보다 더 많이 보실것 같습니다.
실제로 저도 학교 보안 수업에서 CTF를 진행할 때 취약점을 찾아내기 위해서 리버싱을 진행하며
어셈블리 코드만 계속 보고 있었던 적도 있었습니다.
하지만 대부분의 개발자들은 너무 깊게 어셈블리어에 대해서 몰라도 될 것같습니다.
함수 호출과 복귀 정도는 알고 있으면 좋을 것같아 뒤에 소개하겠습니다.
😜컴파일러 VS 인터프리터
컴파일러와 인터프리터는 많이 들어 보셨을 것입니다.
고급언어가 저급언어로 변환되는 방식에는 컴파일 방식과 인터프리터방식이 있는데
컴파일 방식은 컴파일러에 의해 소스 코드 전체가 저급언어로 변환되는 것입니다.
컴파일 과정에서 문법오류를 검출하거나, 실행 가능한지를 확인해주고 오류가 하나라도 있으면 컴파일에 실패합니다.
컴파일이 성공적으로 수행되면 저급언어로 변환되어 목적 코드가 생성되고,
이 목적 코드를 실행 파일로 만들기 위해서 링킹이라는 과정을 걸쳐서 실행 파일인 .exe 파일이 됩니다.
링킹은 정적 링크와 동적 링크가 있고, 런타임 중에 링킹되는 것이 동적 링킹 방식입니다.
링킹은 말그대로 해당 코드에서 외부 라이브러리를 호출해서 실행하기 때문에 그런 라이브러리와 목적 코드를 이어주는 역할을 합니다,
그리고 이렇게 컴파일 + 링킹 합쳐서 빌드라고 합니다.
인터프리터 방식은 인터프리터에 의해 한 줄씩 실행되는 것입니다.
이는 컴파일러 방식에서 문법 검사를 하거나 이런 과정을 기다리지 않고 바로 실행합니다,
만약에 소스코드에 오류가 있으면 그 오류가 발생하기 전까지 실행을 합니다.
둘 중 누가 빠를까?
보통 인터프리터가 빠르다고 알고있지만, 실제로는 컴파일 방식이 더 빠릅니다.
좋은 비유로 외국인 친구에게 책 내용을 알려줄때, 한줄씩 제가 영어로 읽어주는 것과 통번역을 해서 책을 주는 것
그 두가지를 비교하면 당연히 통번역해서 책을 주는 것이 더 빠르게 친구가 읽을 수 있겠죠?
둘은 분리되어 있나?
실제로 두가지 방식은 합쳐서 보통 많이 사용합니다.
자바도 역시 JVM에서 JIT Compiler와 인터프리터가 혼합되어 있습니다.
2. 명령어의 구조
명령어의 구조는 연산코드, 오퍼랜드로 이루어져 있습니다.
연산 코드는 명령어가 수행할 연산이고, 오퍼랜드는 연산에 사용할 데이터나 연산에 필요한 데이터가 저장된 위치입니다.
연산자, 피연산자로 부르기도합니다.
어셈블리를 예로 설명하면
push rbp
mov rbp, rsp
mov eax, 0
pop rbp
ret
push가 연산코드, rbp가 오퍼랜드이고 두 영역을 연산코드필드, 오퍼랜드필드 라고 합니다.
보시는 바와 같이 오퍼랜드 필드에는 rbp,eax 레지스터가 주로 저장됩니다.
오퍼랜드필드에 연산에 실제로 사용할 데이터 보단 데이터가 저장된 메모리 주소나 레지스터가 저장되고
그래서 주소필드라고도 합니다.
오퍼랜드의 갯수에 따라서 0-명령어 ~ 3-명령어로 명칭합니다.
연산 코드는 명령어가 수행할 연산으로 4가지로 주로 나뉘는 데
1. 데이터 전송
-> mov,push,pop
2. 산술/논리
-> add,cmp
3. 제어 흐름 변경
-> jmp
4. 입출력 제어
-> read
외울 필요는 없는 거같습니다.
✨주소 지정 방식
근데 왜 명령어의 오퍼랜드 필드에 실제 사용할 데이터보다 메모리의 주소가 담기는 경우가 더 많을까요?
이는 명령어의 길이 때문인데, 명령어의 길이를 16비트로 가정하고 연산코드를 4비트라고 가정하면
2 - 명령어에서 연산에 사용할 데이터로 6비트짜리 즉 2의 6승까지 밖에 표현을 못합니다.
하지만 주소값을 저장하면 메모리에 저장할 수있는 공간만큼 커집니다.
이렇게 오퍼랜드 필드에 저장된 위치를 찾는 방식을 주소 지정 방식이라고합니다.
유효 주소를 찾는 방법이고, 유효 주소는 데이터가 저장된 위치입니다.
1. 즉시 지정 주소 방식
연산에 사용할 데이터를 직접 명시
2. 직접 주소 지정 방식
메모리 주소를 직접 저장
3. 간접 주소 지정 방식
유효주소의 주소를 저장하는 방식
-> 메모리 접근이 2번일어나므로 제일 느림
4. 레지스터 주소 지정 방식
레지스터를 저장하는 방식
5. 레지스터 간접 주소 지정 방식
유효 주소를 저장한 레지스터를 저장하는 방식
'CS적 감자 > 컴퓨터 구조 & 운영체제' 카테고리의 다른 글
[컴퓨터 구조 - 부록] 부동 소수점 (1) | 2024.11.22 |
---|---|
[컴퓨터구조] 2. 데이터 (1) | 2024.11.20 |
[컴퓨터 구조] 1. 컴퓨터 구조 알기 (0) | 2024.11.18 |
[컴퓨터 구조 & 운영 체제 ] 시작 (3) | 2024.11.14 |