조금 이상한 얘기.. 태초의 컴파일러는 어떻게 컴파일 했을까요?

kirrie의 이미지

제가 아는 바에 따르면, 어떤 소스 코드가 실행되기 위해서는 기계어로 번역하는 과정 (컴파일) 이
필요합니다. 그걸 해주는 프로그램이 컴파일러구요.
심지어 컴파일러도 컴파일 하기 위해서는 다른 컴파일러가 필요하지요.
그렇다면... 태초의 컴파일러는 어떻게 소스 코드로부터 컴파일 되었나요?

정보의 바다에서 스스로 컴파일 되었다는 말씀을 해주신다면 막 웃겠습니다. ㅋㅋ

cleol의 이미지

kirrie의 이미지

그런데 전산학과에 다니면 이런거 다 배우나요?
글 작성하면서 '이렇게 하지 않았을까..' 했던게, 첨부하신 링크의 마지막 방법이었는데.. 정말 그렇게 하긴 하는군요. ㅎㅎ
--->
데비안 & 우분투로 대동단결!

--->
데비안 & 우분투로 대동단결!

cleol의 이미지

저도 전산과를 졸업하지는 않았지만, 컴파일러 과목을 수강하면 배웁니다. 저는 청강을 시도했었는데, 한 달 듣다가 말았습니다.^^;

linlin의 이미지

손으로 컴파일 하면 되죠. 그런 얘기 나오잖아요. C 컴파일러를 일단 C로 짠 다음 이게 완성되면 손으로 한줄 한줄 번역해 실행가능한 컴파일러 바이너리를 만들고... 어쨌든 이건 누가 한번만 삽질 징하게 해 주면 되는 일이니 오래전에 누군가 이미 했겠죠. 일단 C 컴파일러 나오고 나면 C로 운영체제 간단하게 만들면 이식성이 엄청 좋아지니 그 다음부터는 손으로 컴파일러나 오에스 만들 일이 없어지겠죠.

creativeidler의 이미지

예전에 손파일해본 기억을 떠올리게 하는군요. 3명이서 한 화면 보면서 한 명은 흐름 따라가면서 인스트럭션 쓰고 한 명은 레지스터 할당하고 한 명은 검토하고 이렇게 했었다는-_- 10줄 짜리 C 코드를 손파일하는데 1시간 쯤 걸렸던 듯.

sDH8988L의 이미지

태초(Assembly 이외의 그 어떤 언어도 없을 때)에는 이렇게 하지 않았을까요?

일단, 어떤 언어의 Full Set를 만들기 전에 가장 간단하고 필요한 부분만 정의한 후에 그걸 Compile 할 수 있는 Assembly를 손으로 코딩합니다... (Assembly를 제외한 그 어떤 언어도 존재하지 않는다는 것을 가정하므로 Assembly로 짤 수 밖에 없겠죠...)

그럼 그 Assembly로 만들어진 Compiler를 가지고 이제 해당 언어로 짠 프로그램을 Compile 할 수 있습니다...

그 후에 그 언어를 이용해서 언어의 Spec을 조금씩 늘려 갑니다...

이런 식으로 해서 복잡한 언어의 Full Set에 대한 Compiler를 완성할 수 있지 않을까 합니다...

그 이후에 만들어지는 언어들은 이제 기존에 존재하는 언어로 쉽게 Compiler를 만들 수 있겠죠...

정태영의 이미지

해커, 그 광기의 역사 책을 보면, 키보드도 없고 모니터도 없던 그 시절 스위치를 이용해서 프로그램을 입력했다는 얘기가 나오죠. 진정한 바이너리 -_-!!!!!

또 예전에 빌게이츠가 x86 용 베이직을 만들기 위해 제일 먼저 했던 일은 x86 에뮬레이터를 프로그래밍 하는 것이었다고 해요. :)

--
오랫동안 꿈을 그리는 사람은 그 꿈을 닮아간다...

http://mytears.org ~(~_~)~
나 한줄기 바람처럼..

오랫동안 꿈을 그리는 사람은 그 꿈을 닮아간다...

http://mytears.org ~(~_~)~
나 한줄기 바람처럼..

cjh의 이미지

위 링크에 있는것과 비슷한 이야기 같은데 저도 처음에 그런데 관심이 있었습니다.

태초니까 갑자기 64비트 플랫폼에서 작성하는 게 아니라고 한다면,
예전에 8비트 PC 보면 베이직으로 짠 파스칼 인터프리터도 있었지요. 베이직은
어셈블리로 작성할 수 있고, 어셈블리어는 기계어로 작성할 수 있으므로
예를 들면

기계어 -> 어셈블러 -> 베이직 -> 파스칼 or C -> 아무언어...

이런식으로 단순->복잡한 언어 순으로 나아갈 수 있습니다.

--
익스펙토 페트로눔

--
익스펙토 페트로눔

cc1232의 이미지

기계어(10101000 이런거)와 어셈블리어( MOV AX, 0 이런거)는 분명히 다른 것이지요

전에 뭔 책(컴퓨터 역사에 길이 남는 대가들에 대한 책이었음)인가를 보면, 폰 노이만과 그 제자/동료들은 그냥 기계어로 프로그래밍을 했더군요. 제자인가 하는 사람이 기계어로 직접 프로그래밍하는 것이 고달퍼서 어셈블러 같은 걸 만들려고 했었고, 폰 노이만은 그걸 보면서 "그런 쓸데없는 걸 왜 만드냐?"라고 해서 중지했다는 이야기가 있었던 것 같습니다. 폰 노이만은 대단한 천재였기 때문에 기계어로 직접 프로그래밍을 하는 게 별로 어렵지 않았고, 평범했던 제자는 그런 부분이 꽤 짜증났을 겁니다.
암튼 이 일화를 보면 1940년대나 50년대에는 거의 기계어로 직접 프로그래밍을 했다는 것을 알 수 있습니다. 기계어 프로그래밍에 익숙한 사람들이 꽤 있었을테니 최초의 컴파일러가 어셈블러보다는 늦게 나왔지만, 꼭 어셈블러로 작성됐다고는 장담 못하겠네요.
어쨌거나 기계어 아니면 어셈블리어로 최초의 컴파일러를 작성했을 겁니다. (컴퓨터 공학 전공해도 이런거 안 배웁니다. 나만 안 배웠나?)

지금은 하이레벨 언어로 하이레벨 언어 컴파일러를 만드니, 폰 노이만 시대보다는 훨씬 프로그래밍 환경이 좋아지긴 한거죠. 만약 모든 프로그래머가 기계어로 직접 프로그래밍을 한다면, 전 프로그래머가 못 됐을 것 같아요. 물론 지금도 허접이긴 하지만 ^^

vamf12의 이미지

제가 알고 있는 것과 조금 다른데... 쓸데없기도 없지만, 고작(?) 컴파일 하는데 컴퓨터를 사용하는 행위를 용납하지 못했다고 하더군요. ^^
(실제로 컴파일러도 완성했었구요)

mini2g의 이미지

저도 컴퓨터 공학 전공이지만 그런것은 배우지 못했던것 같네요(심지어 컴파일러 수업에서도..)
컴퓨터 아키텍쳐 수업에서 보면 어셈블리어를 기계어로 번역하는 것을 배웠는데요
아마도 기계어만이 아는 문법에 따라 쉽게(?) 알 수 있는 어셈블리어( 당시에는 그 무엇인가 )를 필요로 하게되었고
나름 기계어 코드와 대비되는 명령어를 생각해냈고,
그에 맞게 변형(컴파일) 될 수 있도록 만들지 않았을까요?
예를 들면 어셈블리어로
add $t0, $s1, $s2
는 기계어로
000000 10001 10010 0100 0000 100000
이거라고 배웠는데요
각각 대응하도록 기계어로(헉!) 컴파일러를 만들고
그 후에 어셈블리어로 사용하지 않았을까요?
아마도 어셈블리어와 어셈블러가 동시에 만들어졌을거라 생각되네요

--------------------------------------------------------------
char mini2g[MAX];
if ((기상 후 30분 && 취침 전 30분을 제외한 시간) == (코딩하는 시간))
strcpy(mini2g, "expert");

"overflow" orz...

--------------------------------------------------------------
char mini2g[MAX];
if ((기상 후 30분 && 취침 전 30분을 제외한 시간) == (코딩하는 시간))
strcpy(mini2g, "expert");

"overflow" orz...

지리즈의 이미지

최초의 컴파일러는 cat으로 작성되었습니다. ㅋㅋㅋ

There is no spoon. Neo from the Matrix 1999.

There is no spoon. Neo from the Matrix 1999.

Prentice의 이미지

최초의 어셈블러겠죠. ;) 앗.. 쓰고보니 여기도 오류가;;

지리즈의 이미지

유닉스 조크였습니다.

http://kldp.org/node/13599

Quote:

hacker
uses 'sed' and 'awk' with comfort
uses undocumented features of 'vi'
writes 'C' code with 'cat >' and compiles with '!cc'
uses 'adb' because he doesn't trust source debuggers
can answer questions about the user environment
writes his own 'nroff' macros to supplement standard ones
writes scripts for Bourne shell (/bin/sh)

해커
편하기 위해서 'sed'와 'awk'를 쓴다.
'vi'의 알려지지 않은 기능을 사용한다.
'cat >'을 써서 'C' 코딩을 하고 '!cc'로 컴파일 한다.
소스 디버거를 믿을 수가 없어서 'adb'를 이용한다.
사용자 환경에 대한 질문에 답할 수 있다.
표준 매크로외에 자기의 'nroff' 매크로를 추가한다.
본 쉘용 스크립트를 짠다.

guru
uses 'm4' and 'lex' with comfort
writes assembly code with 'cat >'
uses 'adb' on the kernel while the system is loaded
customizes utilites by patching the source
reads device driver source with his breakfast
can answer any UNIX question after a little thought
uses 'make' for anything that requires two or more distinct commands to achieve
has learned how to breach security, but no longer needs to try

구루
편의상 'm4'와 'lex'를 사용한다.
'cat >'으로 어셈블리 코드를 짠다.
시스템이 로드되는 동안 커널에서 'adb'를 쓴다.
소스를 패치해서 유틸리티를 변경해서 쓴다.
아침을 먹으면서 장치 드라이버 소스를 읽는다.
어떤 종류의 UNIX 질문도 잠깐 생각한 뒤 답할 수 있다.
두개 이상의 명령은 'make'를 사용해서 묶는다.
보안을 어떻게 하는지 배웠지만 더 써먹을 일이 없다.

wizard
writes device drivers with 'cat >'
fixes bugs by patching the binaries
can answer any question before you ask
writes his own troff macro packages
is on a first-name basis with Dennis, Bill, and Ken

위자드
'cat >'으로 장치 드라이버 소스를 짠다.
바이너리 상태로 패치해서 버그를 잡는다.
어떤 질문이든 묻기 전에 대답할 수 있다.
자신만의 troff 매크로 패키지를 짠다.
첫 이름이 데니스, 빌, 켄 으로 시작한다.

god
writes device driver binaries with 'cat >'
creates boot disks with 'dd of=/dev/fd0'
Knows what to do with erde login


'cat >'으로 장치 드라이버 바이너리를 짠다.
'dd of=/dev/fd0' 만으로 부트 디스크를 만들어낸다.

There is no spoon. Neo from the Matrix 1999.

There is no spoon. Neo from the Matrix 1999.

linlin의 이미지

이런 걸 생각해보면 C언어가 처음 만들어 질 때 유닉스와 C 컴파일러를 동시에 C 언어로 써서 만들었다는 점이 참 인상적이죠. 기계어밖에 쓸 수 없는 시스템이 있고 다른 시스템이 아예 없는 상황에서도 C 언어와 유닉스는 손으로 컴파일해서 고수준 언어와 이를 작동시킬 운영체제를 이식시킬 수 있는 기반을 제공해 주니까요.

잘은 모르겠지만 실제적으로는 새로운 시스템이 나오면 크로스 컴파일로 새 운영체제와 컴파일러를 해결하지 않았을까 싶네요. 그리고 운영체제까지 같이 있으니 그 당시로서는 무엇보다 C 언어가 많이 선택되지 않았을까 싶구요.

gcc를 직접 소스를 컴파일 해 보면... 처음부터 gcc 바이너리를 생성하는게 아니라 첫단계에서는 일단 gcc 소스를 컴파일 할 수 있는 조그만 컴파일러 실행파일을 생성한 다음 그 이후에 gcc 소스를 컴파일하죠. 아마도 새 시스템에 gcc를 이식할때는 이 단계에서 cross compile을 하지 않을까 싶네요.