[컴퓨터구조] 내 코드를 컴퓨터는 어떻게 이해를 하고 실행할까?

728x90

안녕하세요🖐

 

오늘은 평소에 궁금했던 내용인 내가 Inellij에서 로직을 작성하면 컴퓨터가 어떻게 이해를 하고 실행이 되는지 항상

궁금했습니다. 그래서 본격적으로 공부를 해보고 제가 공부를 하고 이해한 내용을 포스팅 해보고자 합니다.

 

프로그래밍을 시작한지 8개월정도가 되었지만, 이 부분을 이해하지 못하고 공부를 한게 조금은 창피하지만,   

이번 기회에 제대로 공부를 했으니, 다시는 까먹지 않을 것 같습니다...🤣

 

 

소스코드와 명령어

 💡 개발자가 프로그래밍 언어로 작성한 소스 코드가 컴퓨터 내부에서 명령어가 되고 실행되는 과정을 학습합니다.

 

명령어는 컴퓨터를 실질적으로 작동시키는 매우 중요한 정보 입니다.

 

여기서 질문🖐

우리가 Java같은 프로그램을 실행시키는 Intellj, eclipse에서 프로그램을 동작시키기 위해 짜는 로직은 그럼 무엇인가요?

저희가 만든 로직으로도, 프로그램을 실행해도 컴퓨터는 잘 작동을 하는데 말이죠

 

결론부터 말하면 모든 로직은 컴퓨터 내부에서 명령어로 변환이 됩니다.

 

이번 설명에는 프로그래밍 언어가 어떻게 명령어가 되어 실행되는지 알아보겠습니다.

컴퓨터는 Java 언어를 어떻게 이해할 수 있을까요?

 

개발자는 프로그래밍 언어로 프로그램을 만들고, 컴퓨터는 그렇게 만들어진 프로그램을 실행해 주니까요.

하지만 답은 “그렇지 않다” 입니다.

 

우리가 프로그램을 만들 때 사용하는 프로그래밍 언어는 컴퓨터가 이해하는 언어가 아닌 사람이 이해하고 작성하기 쉽게 만들어진 언어입니다.

 

컴퓨터는 이 언어를 이해하지 못합니다.

이렇게 사람이 이해할 수 있게 만든 언어는 “고급 언어” 라고 합니다

ex) Java, C, python etc..

 

반대로 컴퓨터가 직접 이해할 수 있는 언어는 “저급 언어” 라고 합니다.

저급 언어가 바로 컴퓨터가 이해하고 실행하는 "명령어" 로 이루어져 있습니다.

 

즉 컴퓨터가 이해하고 실행할 수 있는 언어는 오직 저급언어 뿐 입니다.

그러므로 우리가 프로그램 로직을 작성하고 컴퓨터가 이해하기 위해서는

위 과정이 꼭 필요 합니다.

 

저급 언어에는 두 가지 종류가 있습니다.

  • 기계어
  • 어셈블리어

 

기계어

기계어란 0과 1의 명령어 비트로 이루어진 언어 입니다.

위 사진이 바로 0과1로 명령어를 ‘이진수’ 를 통해 표현한 사진 입니다.

엄청 복잡해 보이죠?? 아마 저걸 직접 해석할 수 있는 개발자는 진짜 극 소수일 것이라고 생각합니다. 아마 할 수는 있어도 귀찮아서 절대 직접 하지는 않을 것입니다.

가독성을 위해 그나마 ‘16진수’로 변환해서 표현하기도 합니다.

위 언어를 봐도 엄청 복잡하고, 해석하기 힘듭니다ㅠㅠ🤣

 

정말 우리가 이해할 수 있는 언어를 만드신 분께 항상 감사를 표현하고 존경합니다…

위 사진들을 보면 어떤 로직을 의미 하는지 전혀 모르겠고, 감이 잡히지 않습니다.

 

기계어는 오직 컴퓨터만을 위해 만들어진 언어이기 때문에 사람이 읽기가 엄청 힘듭니다.

그래서 위 과정을 보다 발전시킨 언어가 바로 ‘어셈블리어’ 입니다.

어셈블리어

기계어는 0과 1의 명령어 비트로 이루어져 있지만, 즉 0과 1로 표현된 기계어를 읽기 편하게 번역한 언어가

‘어셈블리어’ 입니다.

위 과정이 기계어를 어셈블리어로 전환하는 사진 입니다.

 

위 어셈블리어 한 줄 한줄이 무엇을 의미하는지도 사실 알 수가 없습니다.

push rbp? 라고 하면 무언가 넣는다? 이정도의 의미로 알고 있을 것이라고 생각합니다.

잘은 모르겠더라도 확실히 0과1 또는 문자와 숫자가 섞인 기계어보다는 훨씬 나을 것이라고 생각합니다.

 

하지만 조금 이해하기 쉬워 졌지만 아직까진, 우리가 원하는 부분까지 도달하지 않았습니다. 어셈블리어 사용해서 코드를 짠다는 것 또한 엄청나게 힘든 작업이 될 것 입니다.

 

말 그대로 어셈블리어는 기계어를 읽기 편하게 만든 것 뿐이지 그걸 토대로 개발자가 개발하는건 무리 입니다😂

그래서 이제 저급언어가 아닌 고급언어가 필요합니다.

 

고급언어는 사람이 읽고 쓰기 편하며, 편리한 문법 등등 다양한 장점이 있습니다.

 

질문🖐 그럼 개발자들은 고급언어만 잘 알면 되지 왜 저급언어 까지 알아야 할까요?

 

어차피 우리가 프로그래밍을 하면 알아서 저급언어로 해석이 되고 로직이 실행이 되는건데, 우리가 저급언어로 개발할 일도 없는데 왜 알아야 할까요?

 

제 개인적은 생각으로는 맞는 말 같으면서도 아닌 부분이 있다고 생각합니다.

보통 웹 개발자는 하드웨어와 밀접하게 맞닿아 있지 않기 때문에 틀린말은 아니라고 생각하지만, 하드웨어와 관련된 임베디드, 게임 등 분야에서는 어셈블리어를 많이 사용한다고 합니다.

 

그래도 주니어 개발자라고 하면은 deepDive 할 정도로 중요한 내용은 아니지만 그래도 고급언어, 저급언어 차이 정도는 알아둔다면 충분히 좋은 내용이라고 생각하기 때문에 알고는 있어야 한다고 생각합니다.

컴파일 언어와 인터프리터 언어

위 부분은 Java언어를 초반에 공부하다 보면 Java는 어떤 언어인지 개념설명이 나올때 본적이 있는 부분 입니다.

결론부터 말씀드리면 Java는 컴파일 언어 입니다.

고급 언어에는 두 가지 변환 방식이 있습니다 바로

  • 컴파일 언어
  • 인터프리터 언어

이번엔 위 두 가지에 대하여 자세하게 알아보려고 합니다.

컴파일 언어

컴파일 언어는 컴파일러에 의해 소스 코드 전체가 저급 언어로 변환되어 실행되는 고급 언어 입니다.

대표적인 컴파일 언어로는 C, Java가 있습니다. 저는 Java 언어를 메인으로 다루는 개발자기 때문에 모든 예시는 Java로 설명을 해보겠습니다🤣

 

그렇다면 “컴파일” 은 무엇일까요?

고급 언어 → 저급 언어 로 변환 되는 과정입니다.

그리고 컴파일을 수행해주는 도구를 컴파일러 라고 합니다.

 

참고로 Java에서는 컴파일러 도구인 Javac를 사용합니다.

 

컴파일러는 개발자가 작성한 로직을 훑으며, 문법적인 오류는 없는지, 실행 가능한 코드인지 등을 따지면서

저급 언어로 컴파일 합니다.

 

중요📢 참고로 컴파일 언어는 한 줄이라도 오류가 있으면 전체 에러가 발생합니다!!

 

코딩 중 에 자주 들어보셨을 겁니다. “컴파일 에러” 라는 말을 들어보신적이 있으신가요??

보통 개발자들은 “컴파일 에러”, “런타임 에러” 이 두가지와 자주 부딪힐 것 입니다. 위 두가지는 다른 부분에서 생기는 에러 임을 꼭 알아둬야 합니다.

  • 컴파일은 말 그대로 컴파일 할 때 생기는 에러
  • 런타임은 말 그대로 실해중에 생기는 에러

두 가지의 차이를 꼭 기억해야 합니다!!

다시 본론으로 돌아가겠습니다. 컴파일을 성공해서 생기는 코드를 “목적 코드” 라고 합니다.

인터프리터 언어

인터프리터에 의해 소스 코드가 한 줄씩 실행되는 고급 언어 이다.

대표적인 언어는 Python이 있습니다.

 

컴파일은 코드 전체가 변환되지만, 인터프리터는 한 줄씩 차례 차례 변환이 된다. 그리고 한 줄씩 저급언어로 변환 될 수 있게 도구 “인터프리터” 를 사용합니다

 

인터프리터 언어는 컴퓨터와 대화하듯 코드를 한 줄씩 실행하기 때문에 소스 코드 전체를 저급 언어로 변환하는

시간을 기다릴 필요가 없습니다.

 

컴파일 언어는 한줄이라도 오류가 있을시 전체 컴파일이 불가능 했지만,

인터프리터 언어는 한 줄 씩 실행하기 때문에 오류가 있는 Line 전까지는 실행이 됩니다.

 

질문🖐 그러면 인터프리터 언어는 컴파일 언어보다 빠르겠네요⁉

 

결론은 아닙니다. 오히려 느립니다.

이유는 컴파일을 통해 나온 목적 코도는 컴퓨터가 이해하고 실행할 수 있는 저급 언어인 반면, 인터프리터 언어는 소스 코드 마지막에 이를 때 까지 한 줄 한 줄씩 저급 언어로 해석하며 실행해야 하기 때문입니다.

 

 

질문🖐 컴파일 언어와, 인터프리터 언어 확실히 구분이 될까요?

 

Java로 기준을 들자면, Java는 컴파일 언어로 알려져 있지만, 저급언어가 되는 과정에서

컴파일과 인터프리터를 동시에 수행 합니다.

 

어떤 언어든, 둘 중 하나로만 작동이 되는게 아니고, 컴파일 언어라고 해서 인터프리터가 불가능한 것은 아니고, 반대로 인터프리터 언어라고 해서 컴파일이 안돼고 그런 장벽들이 사라지고 있는 추세 인것 같습니다.

 

그래서 Java는 컴파일 언어이자 인터프리터 언어 입니다.

 

처음에는 인터프리터 언어로 사용되다가, 컴파일 언어의 장점을 가져와 성능을 향상시켰습니다.

실행 속도를 높이기 위해 JVM의 JIT(Just In Time) 컴파일러는 반복되는 코드를 네이티브 코드로 변환하고, 인터프리터는 컴파일된 네이티브 코드를 직접 사용합니다.

JIT 컴파일러란?

JIT(Just-In-Time)은 실제 실행 시점에 프로그램을 번역하는 컴파일 기법이다. 코드를 매번 해석하지 않고 동일한 코드를 캐싱한다. 자주 사용하는 메소드를 저장하고 해석 없이 바로 실행하여 성능을 향상시킨다.

 

 

이상 프로그램 로직을 컴퓨터는 어떻게 이해를 하고 실행할까? 에 대한 포스팅을 마치겠습니다. 감사합니다.

 

광고는 아니지만, 저는 주니어 개발자들이 CS공부를 해야겠다고 느낀다면

'혼자 공부하는 컴퓨터구조+운영체제' 이 책을 강력 추천 합니다.

이 책을 읽기전의 나와 읽은 후에 나는 개발에 대한 생각하는 관점 자체가 달라져 있을 거라고 생각합니다.

 

ref : 혼자 공부하는 컴퓨터구조 + 운영체제

728x90