2009년 12월 24일 목요일

1장 - 어셈블리의 개념 정의

어셈블리어는 무엇인가 ?

저급 언어 (low-level language)를 언급할 때 기계어 (machine langeuage)와 어셈블리어 (assembly language)를 흔히 묶어서 표현한다.
기계어는 0과 1뿐인 비트 (bit, binary digiti)일 뿐이지 언어라고 할 수 없다. 언어라면 최소한 단어 (word)에 해당하는 무언가가 있어야 하며,
특히 프로그래밍 언어라고 하면 변수 (variable)를 정의할 수 있어야 한다. 기계어에서는 단지 변수가 위치해야 할 영역 (memory)에 0과 1을
기록해주는 방법으로 변수를 결정하므로 단어에 해당하는  무언가가 없기 때문에 언어라고 할 수 없으며, 단지 비트 (bit) 또는 시그널 (signal)
이라고 해야한다. 그런 이유에서 저급 언어는 어셈블리어 뿐이다. 모든 고급 언어는 0과 1이라는 기계어로 바뀌어야 컴퓨터가 알아들을 수 있다.
어셈블리어는 이런 0과 1을 적절히 묶어서 사람들이 이해할 수 있는 연상 코드 (mnemonics)로 표현하는 언어이다. 즉, 기계어의 반복적인 (verbose)
도배에서 인간을 구원해줄 중매자가 어셈블리어이며, 2차 대전 이후 근대 컴퓨터 초창기부터 지금까지 존재하는 이유이다.

어셈블리어를 왜 배우는가 ?

또한, 2차 대전 이후부터 프로그래밍이 가능한 언어 (programmable language)를 개발하기 위해 무수히 많은 사람들이 몰두했으며, 그 첫
프로토타입 (prototype)이 어셈블리어이다. 이후, 많은 고급 언어가 나왔지만, 코볼 (COBOL)처럼 반짝 뜨고지는 고급 언어가 대부분이었다.
어셈블리어는 이와는 다르게 가장 진화가 더딘 언어이며, mov ax, bx 처럼 단순한 "명령어 연산자, 연산자"형식이 대부분이므로, 인텔계열
어셈블리어로 mov ax, bx 라는 명령을 알게되면, 비-인텔 계열 mov %bx, %ax 처럼 연산자 순서가 바뀌더라도 쉽게 그 의미를 짐작할 수 있을
것이다. 비록 기계에 따라 연산자를 바꿔야하지만, 그 명령 자체의 의미는 비슷하기 때문에 아무 기계에서나 어셈블리어를 배워두면 다른
기계에서도 어느 정도 코드의 내용을 유추할 수 있다.

 대부분의 고급 언어는 프로그래머를 컴퓨터와 격리시키는 상술을 쓰고 있다. 그래야 라이브러리 같은 부수 아이템을 팔 수 있다. 반면 프로그래머는
갈수록 라이브러리 코드에 의존할 수 밖에 없다. 어셈블리어는 대부분의 라이브러리를 직접 만들어 쓰거나 다른 어셈블리 프로그래머 개인이 만든
라이브러리를 입맛에 맞게 고쳐쓰기도 한다. 즉, 특정 회사의 종속에서 조금은 벗어날 수 있으며, 직접 코딩하다보면 시스템의 작동 방식이 훨씬
명쾌하게 이해되므로 더 나은 코딩에 도움이 되기도 한다. 반면 시스템 코딩을 하다보면 당연 그 시스템에 밀접한 코드가 나올 수 밖에 없으므로,
상대적으로 포팅의 문제를 접하기도 하는데, 그건 고급 언어에서도 라이브러리가 지원해주지 않으면 마찬가지다. 예로, C에서 printf()라는 함수를
다른 시스템에서 지원해주지 않는다면 (물론 필수 함수라서 어떻게서든 지원하려고 할 것이다.), 포팅이 문제가 되는 것은 마찬가지다.

어셈블리어를 배우는 다른 이유로 리버스 엔지니어링 (reverse engineering)을 들 수 있다. 이 용어는 컴퓨팅쪽에서 근래에 사용되었으며,
그 이전엔 크래킹 (cracking)이라는 용어로 사용되었다. 둘다 어셈블리 코드를 토대로 이뤄지며, 어감상 리버스 엔지니어링이 코드를 재사용하는
느낌이 약간 더 강하게 베어있으며, 크래킹은 원저작자의 의도와는 다르게 자신의 입맛에 맛게 뜯어고치는 느낌이 약간 더 강하다. 비유를 들자면,
음악에서 샘플링과 표절의 차이 정도에 해당한다. 하지만 아직까지는 두 단어가 거의 비슷한 의미로 사용된다. 참고로, 자신이 만든 코드를
뜯어고치는 것은 자유며, 원저작의 코드를 함부로 뜯어고쳐서 개인적으로 쓰는 것까지도 용인되지만, 이를 배포하면 저작권에 위배될 수 있다.

모든 고급 언어로 만든 프로그램은 결국 0과 1로 인코딩 (encoding)되고, 그 0과 1을 몇개씩 묶어서 사람이 연상하기 좋은 (mnemonic)
명령으로 변환하는 것을 역어셈블이라고 한다. 다시 말해 고급 언어로 코딩한 것이라도 어셈블리 프로그래머는 그 역어셈 코드를 살펴볼
수 있다. 물론 그 코드의 의미를 알아내는 것은 전적으로 개인의 어셈블리 지식과 역어셈블러 (disassembler)의 해석 능력에 달렸다.

똑같은 단어 add도 어셈블리 프로그래머와 산수를 가르치는 선생님이 느끼는 의미는 다르며, 같은 add라는 단어도 A라는 사람이 설명하는
것과 B라는 사람이 설명하는 것이 다르듯이 여러 역어셈블러는 조금씩 다르게 해석해준다. 역어셈블러가 산출한 코드를 해석하기 위해
어셈블리어를 배우는 사람도 있다. 예로, 바이러스 코드나 시스템에 취약점을 집어내는 코드를 분석하는 것을 들 수 있다.

어셈블리어는 왜 꺼려하는가 ?

사실 어셈블리어로 코딩하는데는 기겄해야 add, mov, push등의 단순한 명령 약 100개 정도 (컴퓨터에 따라 더 많을 수 있다)만 외우면 된다.
그 100개를 못 외워서가 아니라, 상황에 맞게 써야하기 때문이다. 똑같은 mov 명령도 "mov 메모리, 레지스터" 형식을 쓴 것과 "mov 레지스터, 메모리"
형식을 쓰는 것이 전혀 반대의 뜻이 될 수 있기 때문이다. 명령만 안다고 되는 것이 아니다. 인텔 계열 (주로 여기서 언급할 masm이 인텔계열이다.)에서
전자는 저장 (store, 또는 save)이라고 표현하고, 후자는 로드 (load)라고 한다.

또한, 어셈블리어의 약점 중의 하나가 레지스터 내용을 머리로 추적해가면서 코딩해야 한다는 점이다. 코딩을 하면 할수록 내 머리가 CPU처럼 작동하는
것처럼 느껴지기도 하는데, 이는 코딩 툴이나 디버깅 유틸리티가 부족하기 때문이다. 즉, 내가 기록한 어셈블리 명령을 즉석에서 베이직 컴파일러처럼
해석 (interprete)해주는 유틸리티가 있으면 극복이 가능하지만, 그런것을 만들 여유가 없기에 머리로 계속 추적해야 한다.

위의 두가지외에 가장 문제가 되는 것은 라이브러리의 부족이라고 할 수 있다. 예로, C 언어는 C의 표준을 정하는 위원회 (ANSI)가 있지만, 어셈블리어는
그런 것 조차 없으며, 반강제로 코딩 규칙을 강요하지도 않을 뿐더러, 필요하면 라이브러리를 직접 만들어 써야한다. 즉, 자유와 수고가 따른다.

이 3가지 이유외에도 고급언어로 100줄 코드가 어셈블리어로 해석하면 10000줄 코드가 될 수 있다. 그 이유는 위에서 설명했으므로 충분히 알 것이다.
그 말은 고급 언어는 불필요한 코드 (overhead code)가 너무 많이 들어간다는 역설이 된다. 장점만 있는 것은 세상에 아무것도 없다.

어셈블리어는 이처럼 오버헤드를 최대한 줄이기 때문에 코드 자체가 작고 빠르다. 그런 이유로 고급 언어 컴파일러는 상당수가 인라인 어셈블리를
지원하며 컴파일러가 최적화를 못해주는 부분도 어셈블리 코드를 보고 직접 디버깅하여 최적화된 컴파일러 코드의 100배 성능을 끌어낼 수도 있다.
반대로 잘 못 만든 어셈블리 코드는 컴파일러가 만든 코드보다 100배 느려질 수도 있다. 디지털 세상에서 속도와 용량이라는 두 장점을 갖춘 언어가
바로 어셈블리어이다. 그럼에도 불구하고 "어렵다"는 선입관 때문에 외면을 많이 받고 있으며, 이미 대세는 MS에서 밀어주는 컴파일 언어가 아닌가 ?
작고 빨라 어느 언어에라도 이식시킬 수 있는 장점을 가졌건 말건간에 많은 사람들이 대세를 따라서 상대적으로 외면받는 언어중 하나가 어셈블리어이다.

그럼에도 시중에는 어셈블리 프로그래밍 관련 정보가 왜 그리 적은가 ?

시중에 어셈블리 관련 서적이 몇 되지도 않을 뿐더러, 대부분 최신 프로그래밍 패러다임을 못 따라가고 흡사 전래 동화 들려주듯이 옛 방식을
고수하기 때문이다. 옛 방식을 고수하면 보편성을 확보하기가 좋다. 다른 이유로 최신 패러다임을 어셈블리어로 구현하려면 시간이 너무 많이
걸리기 때문이기도하다. 똑같은 코드도 처한 상황에 따라 다르게 해석될 수 있다. 그러므로, 어셈블리어에서 다룰 수 있는 범위가 너무도
광범위하며 시중에 나온 서적은 그 빙산의 일각을 서술한 것에 불과하다. 나 또한 마찬가지다. 내가 서술할 어셈블리 정보 또한 줏어들은 극히
일부의 정보에 불과하다. 내 게으름을 변명하자면, 한평생을 배워도 못다 배우는 언어가 바로 어셈블리어이다. 2차 대전때부터 지금까지 많은
사람들에 의해 구전되어 내려온 정보를 한 개인이 어찌 다 배우겠는가 ? 이렇게라도 변명을 하는 나를 용서해주길 바란다. 물론 최선을 다하겠지만,
나에게 너무 많은 기대를 하진 않을 것이다. 나는 다만 따로 언급할 필요가 없는 것은 걸러내고 내가 보기에 알짜배기만 골라서 다루면 될 것이다.


누구를 위해 이 언어는 존재하는가 ?

단순히 말해서 단순한 사람들을 위해 존재한다고 할 수 있다. 예로, 피보나치 수열이 무엇인가 ? 라고 누군가 묻는다면, F2 = F1 + F0 이라는 둥의
고차원적인 대답은 고급 언어 유저나 하는 것이다. 어셈블리를 배운다면 단순히 "누적합"이다고 대답할 수 있어야 한다. 물론 지나치게 단순하게 표현한
것인지 모르겠지만, 그런 마인드가 갖추어진 사람들에게 적합하다고 예를 든 것에 불과하다. 어셈블리어라는 저급 언어를 쓰는 우리는 저급한 표현으로
대답을 해주는게 상책이고, 어셈블리어로 코딩하다보면 또한 자연스레 머리가 단순해짐을 느낄 것이다. 다른 예로, 변수 하나를 선언하려고
strNameOfAllMyBestFriends 식으로 표현하는 것은 고급언어에서나 통한다. 코딩하다보면 자연스레 이름짖는 방식도 짧아짐을 느낄 것이다. 이것이
코드라는 사막에서 논리라는 오아시스를 찾는 한 방법이다. 간단한 프로그램 하나를 역어셈블하여, 백과사전 한세트 분량의 방대한 코드에서 허우적대다보면,
단순함이 얼마나 도움이 될지는 직접 해보면 알 것이다.

어셈블리어는 프로그래머의 창의력을 높여준다. 이 말은 한때 유명했던 어셈블리 프로그래머인 피터 노턴 (Peter Norton)이 한 말이다. Windows 관련
프로그래밍 베스트 셀러를 낸 찰스 페촐드 (Charles Petzold)도 한때는 어셈블리 프로그래머였다. 게임 프로그래머로 잘 알려진 마이클 애브래시
(Michael Abrash) 또한 어셈블리 프로그래머였다. 그 외에도 유명한 코더들은 위기가 닥치면 마지막 보루로 어셈블리어에 많이 기대왔다. 심지어 어떤
프로그래머는 리버스 엔지니어링 관련 포럼에서 타인이 만든 프로그램을 리버싱하는 방법을 알려주면서 자신이 만든 프로그램을 광고하기도 한다.
그만큼 어셈블리 코드를 두고 치열한 정보전 (?)이 일어나는 곳이 바로 이 분야며, 난 어셈블리 프로그래밍이 국력 (?)을 키워줄 수 있다고 믿는다.
그렇더라도 코드나 컨텐츠로 승부해야지 얄팍하게 애국심을 상술에 적용하는 마케팅은 언젠가는 자신의 배를 채우려는 이기심으로 사람들의 머리에
남을 것이다.

몇몇 용어에 대해서

어셈블리 프로그래밍하면서 제일 먼저 마주대하는 용어를 3개 들라면, register, address, operand를 들 수 있다. 이는 국어사전상 레지스터, 어드레스
(주소), 피연산자로 정의되어있지만, 나는 레지스터, 어드레스, 연산자라고 부른다.

operand를 왜 연산자라고 하는가 ? -and 라는 접미어는 영단어에서 피동의 의미를 지니고 있다는 걸 모르는게 아니다. 하지만, 능동과 피동을 굳이
구분해야 할 필요가 없으며, 그냥 "연산의 대상"이라는 용어로 "연산자"를 쓰면 서로 쉽다. '피-'가 붙은 단어를 개인적으로 싫어해서도 이지만, 만약
능동과 수동을 엄격히 구분해서 표현한다면, operator 또한 '피연산자'라고 칭해야 한다. 왜냐하면 연산을 행하는 주체는 인간이기 때문이다.

어셈블리 프로그래밍에서 sizeof/offset/and 등의 masm등의 어셈블러가 자체 제공하는 연산자도 있다. 그렇다면 위의 연산자 호칭과 서로 중복되므로
구분해야 옳지만, 어셈블리 프로그래밍을 해본 사람이람면 cpu 명령인지 masm 등의 어셈블러가 자체 제공하는 연산자인지를 구분 못하는 사람이 없다.
그러므로 굳이 구분해야 할 필요도 없다. and를 예로 들자면, 이는 CPU 명령에도 있고, 어셈블러 (masm) 키워드인 연산자에도 있다. 서로 중복되는
경우만 연산자/피연산자로 구분하면된다. 예로,

and ax, 1234h and 3456h

이 명령은 masm에서 유효한 명령이다. 이처럼 서로 중복될 경우 앞의 and는 '명령', 뒤의 and는 '연산자'라고 부른다해도 피-연산자를 쓸 이유가 없다.
피-연산자는 단지 설명을 위해 존재하는 추상적 단어일 뿐이다. 엄밀히 말하자면 어셈블리 프로그래밍을 할 줄 모르는 사람이 사전을 만들면서 사전의
부피를 늘리는 역할만 하는 억지로 번역해 넣은 쓸모 없는 단어에 불과하다. 우리는 어셈블리 코딩을 할 것이므로 그런 무책임한 말장난에 놀아날 필요가
없다. 프로그래밍한다면 차라리 코드로 장난친다면 몰라도 말장난을 해야 할 필요는 없다.

국어 사전의 "-법"을 무시해서가 아니다. 나 또한 국어 사전이 있기에 이 글을 쓴다. 하지만, "국어"라는 말 자체가 "우리말"로 바뀌어져야한다고
생각한다. 알다시피 근대 컴퓨터는 2차 대전 이후 알파벳 문화권에서 만들어졌다. 그러므로 우리는 그런 용어를 "원어 -> 한자어 -> 한글"이라는
과정을 거쳐서 해석할 필요는 없다. 하지만, 이는 이상에 불과하지 현실은 그렇지 못하는 것을 잘 알것이다. 그러므로 어느 정도 타협을 하긴 하되,
무분별한 한자의 "오남용"을 따라할 필요는 없다. 우리말/글을 오염시키는 "한자 바이러스", 시대의 흐름을 따라가지 못하는 패배자들이 "사상"이라고
거짓으로 꾸며대는 말장난 도구에 불과할 뿐이다. 마지못해 영어를 쓸 뿐이지 영어라고 예외가 될 순 없다. 다만 여기서는 될 수 있으면 내나름대로
쉽다고 느껴지는 용어를 사용하도록 노력하겠다.

1234h와 3456h는 expression이고, 뒤의 and는 operator이고, 이 operator의 작동 결과물이 operand이며, ax라는 다른 operand와 and라는 instruction으로
연산을 수행한다고 해야하지만, 그러기엔 말꼬리가 너무 길어진다. 반면, 1234h와 3456h 두 연산자를 and 연산하여 그 결과를 ax와 and 연산하라. 이
얼마나 명쾌하고 간략한가.

register : 이거 어셈블리 프로그래머라면 시도때도 없이 달고 다니는 단어이다. 하지만, 그렇다고 '등록기'라고 한다면 이는 진짜로 무식한 콩글리시에
불과하다. 왜냐하면 레지스터는 CPU를 만든 사람들이 붙여진 준-고유명사 쯤에 해당하는 단어이기 때문이다. "홍길동"이라는 이름을 한자 하나 하나 해석해서
부르는 것 쯤에 해당한다. 나는 "레지스터"라고 그대로 부르기로 한다.

address: 이 단어도 엄청 많이 쓰는 단어이며, 명사와 동사로 경우에 따라 다르게 쓰여진다. 나는 명사일 경우 "주소(또는 어드레스)"를 편할 대로 골라서
부르며, 동사일 경우 "어드레스한다", "액세스한다", "접근한다" 등으로 경우에 따라 다르게 부른다.

parameter vs argument: 이 또한 상당히 골치 아픈 영단어에 불과하다. 둘다 편히 인자 (또는 매개변수)라고 하면 의미상 혼동을 일으키지 않지만, 간혹
둘을 구분해야 할 경우가 있다. 이 경우 "지표"의 뜻을 지닌 parameter 형식 인자, 그 지표를 따르는 복사본인 argument를 실제 인자 (실인자, 실인수)
등으로 부르면 된다.

signed vs unsgigned: 이 또한 "부호있는" "부호없는"으로 해석하지만, 나는 편의에 따라 "음수" "양수" 또는, "부호를 인정하는" "부호를 무시하는",
또는 그대로 "사인드/언사인드" 부르기로 한다. 어셈블리 언어에서 부호는 음수/양수를 판단하는 "특별한" 부호이다. 일상에서 signature의 의미와는
상당히 다르다.

sign-extended vs zero-extended: 이는 앞의 부호의 개념을 확장한 용어이며 둘다 비트를 세팅하는 용어이다. 다만 sign-extended는 양수일 경우 0으로
비트를 채우고 음수일 경우 1로 비트를 채우며, zero-extended일 경우 음수/양수와 상관없이 0으로 채운다. 나는 이를 "부호-확장" "제로-확장"이나,
기타 의미를 전달하는데 혼동을 일으키지 않을 정도로 상황에 따라 달리 표현할 것이다.

clear vs set: 이는 특정 비트를 지우거나 설정하는 용어이다. 지운다는 것은 0으로 만든다는 뜻이고 설정한다는 것은 1로 만든다는 뜻이다. 즉, 둘다
만드는 것은 같으며 0이냐 1이냐만 차이를 가진다. 나는 이를 "클리어" "세트" 또는 "지운다" "설정한다", "0으로 만든다" "1로 만든다" 등으로 표현하고
역시 상황에 따라 혼동하지 않게끔 달리 표현할 것이다.

constant vs literal constant vs immediate: 이는 모두 "상수"로 표현하며, 구분해야할 경우 constant - 상수, immediate - 임시값/또는 즉시값,
literal constant - 문자화 상수 (또는 그냥 상수)로 표현하기로 한다.

대표적인 것 몇개만 나열했지만, 이외에도 용어로 표현하기 곤란한 것도 너무 많다. 예로, nibble이라는 단어는 jargon, 즉, 은어이다. 이는 비트 4개를
묶어서 표현하는 은어이며, 반면, byte는 term, 즉, 용어이다. 은어가 공인되면 용어가 된다. 하지만, 아직 니블은 비공인에 가깝다. 그럼에도 여기서는
니블을 자주 쓰게 될 것이다. 다른 예로, truncate 이 단어도 자주 쓰는데, "잘라내다" "버리다" 쯤에 해당한다. 이는 실생활에서 그리 적용되지만, 이
단어는 예전에 자동차가 처음 만들어질 때 자동차의 트렁크(trunk)에서 유래되었다고한다. 하지만 어셈블리에서 truncate는 특정 비트를 버리는 것 쯤에
해당한다. 심지어 많은 네트웍 "전문가"를 자청하는 사람들이 router를 "라우터"라고 부른다해서 이들을 비난만 할 수 없다. 프로그래밍/코딩은 컴퓨터
여러 분야에서 적용할 수 있지만, 그렇다고 여기서 컴퓨팅 관련 용어를 모두 재정립해야할 필요도 없다. 난 국어학자가 아니다. 이외에도 너무도 많아
여기에서 열거조차 다 할 수 없으며 필요할 경우 설명을 하던지 하겠다.

하지만 용어는 어디까지나 용어일 뿐이지, 코딩/프로그래밍에는 별 영향을 주지 않는다. 즉, 말에 현혹되지 말고 의미에 현혹되라.


그렇다면 당신은 누구길래 감히 어셈블리어를 논하는가 ?

나는 어셈블리어를 만든 사람도 아니며, 그저 어셈블리 코딩 자체를 즐기는 아마추어에 불과하다. 만약 당신이 어셈블리어를 배워서 어딘가에 활용할    
궁리를 한다면 당신 또한 나처럼 괴짜 (geek) 기질이 있는 사람일 것이다. 괴짜 마인드를 가진 사람에겐 다른 것은 필요없다. 단순히, 모르는 것을  
세상 끝까지라도 알아내려 찾아가면 그걸로 된다. 그런 마인드가 없으면 어셈블리 프로그래밍에 아예 발을 담그지 않는게 나을 것이다. 컴퓨팅 50년 
역사가 고스란히 블랙박스처럼 코드에 내재되어 또는 어셈블리 프로그래머간에 구전되어 (?) 내려오는 언어가 어셈블리어이다. 이를 모두 배우려면  
시간도 많이 걸리며 정보력도 많이 필요함을 짐작할 것이다. 더구나 프로그래밍이란 것은 이론 + 코딩이랄 수 있다. 즉, 정보력 + 이론에 창의력이라는
알파 인자까지 더 요구되니, 사법 고시를 준비한다는 마음으로 어셈블리 프로그래밍을 해야 할 것이다. 사법 고시는 그나마 창의력은 덜 필요하지 않은가 ?

가만히 생각해보면 프로그래밍이 요리와 유사한 점이 많다. 아마도 당신은 나보다 훨씬 뛰어난 코딩 요리 실력을 갖게 될 것이다.
왜냐하면 나는 기본적인 내용을 알려주는 사람이 너무 적어서 인터넷을 몇년간 떠돌아다녔으며 내가 처음 어셈블리 프로그래밍을 배울때만해도 시중에
어셈블리 관련 서적이 거의 없었다. 나는 1999년 처음으로 어셈블리 프로그래밍 관련 홈페이지를 만들었다. 그 시절 관련 사이트 주소만 2천개의
링크를 가지고 있었으며 거의 매일 깨진 링크가 있나 확인하는게 나의 일과중 하나였다. 지금은 그 홈페이지가 공중으로 날아갔다. 인터넷 무주택자의
설움을 10년 넘게 겪으면서 어셈블리 관련 레퍼런스가 될 사이트를 구성하는 것이 나의 유일한 목표였다. 애써서 만들어둔 링크가 깨져가고 (그렇다,
나보다 먼저 10년 넘게 어셈블리 프로그래밍을 한 사람도 접고 어느새 다른 분야로 진출한 경우가 많았다.), 애써서 만든 홈페이지 ISP가 M&A 당해서
계정이 날아가고, 몇달 로그인안했다고 샘플 코드를 정리해둔 홈페이지도 계정이 삭제당해버리고, 새로 만든 홈페이지는 뜬금없이 대문짝만한 광고를
ISP가 끼워넣고, 어쩔땐 트래픽을 "이빠이" 제한하여 로딩 화면 보느라 지쳐보기도 했다. 아마도 나처럼 인터넷 무주택자의 설움을 겪어본 사람은 무슨
말인지 이해할 것이다. 21세기 돼지털 (digital) 세상에서 "인터넷 난민"이라니...

그런 점에서 내가 만든 이 작은 정보 부스러기도 어떤 이에게는 아주 소중한 정보가 될 수 있고, 어떤 이에게는 그저 인터넷 공간을 낭비하는 보거스
데이터에 불과할 수 있음을 난 잘 알고있다. 나는 후자가 되지 않기 위해 나름 이 사이트를 열심히 꾸밀 것이다. 당신 또한 이 블로그에서 쓸만한거
하나라도 건지면 그대에게 도움이 되서 나 또한 즐거울 것이다. 즉, 이 블로그는 나를 위한 것이며 나와 비슷한 고민을 겪는 사람들을 위한 것이지,
누구를 가르치거나 훈계하려는 목적은 아니다. 또한 나는 이 블로그를 꾸미면서 "A는 B이다" 식의 사상을 단순 "주입"하는 정리는 자제하려 한다.
이런 정리는 관련 서적에 얼마든지 나와있기 때문이며, 아무 도움이 안된다는 것을 알고 있기 때문이다. 대신, "A는 어떻게하여 어떻게 작동한다"는
식으로 어찌보면 조금 장황할 수 있지만, 말보다 실천을 중시여기므로 샘플 코드를 들어가면서 설명하려 노력하겠다. 즉, 이 블로그에서 다루는 내용은
어떤 이에겐 아무 쓸모도 없지만 다른 어떤 이에게는 책에서 못배운 내용을 얻게될 수 있을지 누가 아는가 ? 만약 그 중에 하나라도 쓸만한 걸 건지면
도움이 되서 나 또한 즐겁지 않겠는가 ? 이 블로그는 그런 점에서 내가 배워나가는 과정을 설명한 것이다.

만약 이 블로그에서 잊고 지냈던거나 모르고 지냈던 무언가를 하나라도 알게 된다면, 활용할 줄 알아야지 의미가 있다. 외운다고 코딩이 되는 것이
아니다. 물론 외우지 않고 소스의 일부를 돼지털 만능 키워드인 copy & paste 테크닉으로 쉽게 문제를 해결하기도 할 것이며, 나 또한 마찬가지다.
당신이 나에게서 무언가를 배웠다면 이는 어디까지나 내 우물 속에서 설명한 세상의 일부를 배운 것이다. 하지만 내 우물 속에 당신마저 갇혀 지낼
필요는 없다. 나를 밟고서라도 뛰어올라 넓은 세상으로 나가보라. 그리고 세상에서 배운 것을 나에게도 가르쳐주면 당신은 나의 스승이다.

수년간 어셈블리 프로그래밍해온 사람도 결국 포기하고 다른 분야로 나간 사람을 나는 많이 봤다. 즉, "장인 정신"없이 무턱대고 덤벼들었다가 나중에
시간만 허비했다고 날 원망해봤자 때는 이미 늦을 지 모른다. 당신에게 두 갈래 길이 있다. 왼쪽으로 갈 것인가 오른쪽으로 갈 것인가 ? 만약 둘 중
하나를 취한다면 취하지 않은 다른 길에 미련을 갖지 말라. 당신이 선택한 것이니...

댓글 없음:

댓글 쓰기

블로그 보관함