월요일, 12월 31, 2007

핸드폰 소설

음...

일본에서 인기있는 item 중 하나인 "핸드폰 소설" 이다.
아래는 그 중 하나인 영화화 되기도 했던 ~恋空~(Koizora) 이다.

~恋空~ 공식 사이트
http://koizora.jp/

~恋空~ 핸드폰 소설보기
http://ip.tosp.co.jp/BK/TosBK100.asp?I=hidamari_book&BookId=1&SPA=200

아래는 국내에서 서비스 중인 모바일 소설 "1,000 字 소설" 서비스에 대한 기사이다.
http://www.inews24.com/php/news_view.php?g_serial=246155&g_menu=020500&pay_news=0


일본처럼 모바일용 초미니 소설 뜰 까…모비닷컴, SKT에서 서비스
김현아기자 chaos@inews24.com
모바일 콘텐츠 업체 모비닷컴(대표 이상교 www.mobbie.com)은 SK텔레콤 무선 인터넷 네이트(NATE)에서 '1,000字 소설' 서비스를 시작한다.

'천자소설'은 젊은이 취향을 고려해 빠른 호흡의 문체로 10분이내에 재미를 느낄 수 있도록 한 글자수 4천자 이내의 초미니 단편소설.

현재 모바일에서 서비스되고 있는 m-북, u-북은 출판된 소설을 그대로 옮겨놓은 것. 하지만 '천자소설'은 길이와 문체가 다르다.

모비닷컴 관계자는 "일본, 중국을 중심으로 인기를 끌고 있는 모바일 콘텐츠 중 하나가 바로 소설 장르"라며 "활자 이탈현상이 가속화되고 있는 일본에서는 모바일 소설이 새로운 신세대 문화코드로 자리매김 하고 있다"고 설명했다.

일본의 유명 출판사인 신쵸사의 경우 모바일 소설 사이트인 휴대문고를 열어 유료회원만 5만명이 넘는 인기를 누리고 있다. 나이토미카(35)라는 모바일 소설작가가 등장, 수천명의 팬을 확보하고 있는 것으로 알려졌다.

'천자소설'은 무협, 판타지, 추리 등의 장르문학과 순수문학을 모두 포함한다.

이상교 사장은 "모바일 천자소설은 이용자에게는 특화된 전용 서비스를, 작가에게는 새로운 매체와 시장에의 참여를, 출판사에게는 부가 수익원이 될 수 있는 윈윈 콘텐츠"라고 설명했다.

SKT의 NATE>운세학습생활예매>책책책! m-Book(또는 **19 + NATE 버튼)을 통해 감상할 수 있다.

모비닷컴은 2월 한 달간 모바일 천자소설 공모전을 실시, 모바일 천자소설 작가 발굴에 나선다. 최우수상 1명에게는 상금 100만원이 주어진다.

IT는 아이뉴스24, 연예스포츠는 조이뉴스24

금요일, 12월 21, 2007

혼자서 공부하는 법

Source:
http://snowall.tistory.com/71


난 공부를 혼자서 했다.
...라고 말하면 99.9%쯤은 거짓말이지만. 아무튼 혼자서도 공부를 하긴 했다.

요새는 학원, 과외, 인터넷 강의 등 공부할 수 있는 여건이 잘 갖춰져 있어서 스스로 공부하지 않아도 돈만 내면 교사가 눈앞에서 다 가르쳐주는 세상이 되었다. 물론 이게 나쁘다는 건 아니다. 하지만 이것은 문제의 시작점이 될 수 있다. 워낙 편하게 공부를 하다보니, "요점정리"라든가 "필수 기출문제"라든가 하는 공부하기 쉽게 가공된 정보만 머릿속에 들어오고 따라서 직접 중요한 것과 중요하지 않은 것을 스스로 따지는 것이라든가, 안풀리는 문제를 며칠씩 붙잡고 머리싸매면서 풀어보는 것이 멍청한 짓이 되어버린 세상이 된 것이다. 하지만 공부는 그런게 아니다. 답이 있든 없든, 내가 모르는 것을 알아가는 것 자체에 중요한 의미가 있는 것이다. 정확히 말해서, 내가 학교나 학원에서 배워야 하는 것은 지식이 아니라 지식을 만들어내는 방법이다. 아주 유명한 격언이지만, 물고기를 잡아주기보다는 물고기 잡는법을 가르쳐 줘야 한다는 말이 있다. 요새는 모두 물고기를 잡아준다. 생각해보니, 모든 사람들이 물고기를 잡을줄 알게 된다면 물고기 팔아서 먹고 사는 낚시꾼들은 다들 굶어 죽겠군.
스스로 공부하는 능력을 잃어버린 사람은 결국 타인에게 의존하는 수동적인 사람일수밖에 없다. 세상에는 사람이 모르는 것이 아주 많이 있는데, 그중에서 다른 사람에게 배울 수 있는 것은 아주 조금이다. 나머지는 스스로 알아서 배워야 하는 것이다. 하지만 스스로 공부를 할 수 없다면 결국 아주 많은 사람들에게 배워야 그나마 알게 된다는 얘기가 될텐데, 이건 곧바로 지출로 이어진다. 지식을 거래하는 사회에서는 지식을 만들어내지 못하면 자신의 자산이 줄어들어야만 할 것이다. 따라서 혼자서 공부하는 능력을 키우는 것은, 좋은 대학에 가는 것이나 성적을 잘 받는 것보다 훨씬 중요한 성공의 요소가 된다.
이런 이유로, 이 글에서는 혼자서 공부하는 방법에 관하여 논의해 볼 생각이다.

우선, 모든 수동적 공부방법을 끊어라. 과외, 학원, 인터넷 강의 등은 별 도움이 안된다. 물론 모든 것을 다 끊으라는 것은 아니고 적절한 타협점을 찾아서 필요한 과외, 필요한 학원, 필요한 인터넷 강의는 들어야겠지만 거기에 의존하는 태도를 버리기 위해서는 일단 모든 것을 끊고 시작하는 것이 좋다. 이 시기는 빠를수록, 어릴수록 좋다.

두번째로, 모르는 것에 대한 두려움을 없애야 한다. 당신이 이 세상의 모든 지식을 전부 아는 것은 불가능하다. 당신 스스로가 잘 알다시피 당신은 아무것도 아는 것이 없을 것이다. 아직 배우지도 않았으므로 모르는 건 당연한 일이고 따라서 그걸 이상하게 생각하는 사람들은 전부 이상한 사람이라고 할 수 있겠다. 모르는 건 당연한 일이니까 두렵고 자시고 할게 없다.

세번째로 가져야 하는 것은 모르는 것을 알고자 하며 그 알아가는 과정을 즐기려는 마음이다. 누군가로부터 손쉽게 얻어낸 지식은 모래위에 모래성을 쌓는 것과 같아서 파도가 휩쓸고 가면 전부 무너진다. 더군다나 현대 지식 사회는 지식이 폭풍처럼 만들어져서 온세상에 휘몰아치는 세계이다. 그 폭풍속에서 버텨낼 수 있는 견고한 지식을 쌓아두지 않으면 배우나마나한 지식이 되어버린다.

넷째로, 너무 어렵거나 모르는 것은 물어보면 된다. 하지만 대답해 주는 사람에게 의존하지 말고, 스스로 답을 찾는 것을 연습해라. 대답해 주는 사람이 내가 질문하는 것의 모든 것을 대답해줄 수는 없다. 그 역시 사람이니까. 스스로 답을 찾아내는 것을 연습하지 않으면, 아무도 대답해줄 수 없는 자신의 문제에 답을 알 수 없게 된다. 그 문제가 별로 중요하지 않다면 모르겠으나, 아무도 정답을 모르는 문제는 대부분 대단히 중요한 경우가 많다.

다섯번째로는 지겨움에 대한 내성이다. 모르는걸 끝도없이 붙잡고 있으면 당연히 지겹다. 사실 별로 중요하지 않은걸 끝도없이 붙잡는건 시간낭비겠지만, 아무리 중요한 내용이라도 모르는걸 계속 고민하다보면 지겨워서 관두고 싶어진다. 이 지겨움을 알아냈을 때의 기쁨을 기대하면서 즐거움으로 승화시켜라. 이정도 할 수 있으면 절에 들어가서 스님이 되어도 이겨낼 수 있을 것 같다. 그리고 아무래도 모르겠다면 물어봐라.

여섯번째로, 평소에 책을 읽어라. 책을 많이 읽어두는 것은 잡다한 지식을 많이 얻을 수 있기 때문에 좋다. 그리고 독해력이 향상되어 중요한 공부를 해야 할 때 빠르게 공부를 할 수 있게 된다. 책을 그냥 읽으면 안되고 그 안의 내용을 자기 것으로 소화시키는 것 또한 중요하다. 책을 전부 암기하라는 얘기가 아니라 나중에 어떤 필요한 내용이 있을 때 "아, 그 책에서 봤던 내용이다!"라고 외칠 수 있을 정도의 어떤 느낌을 기억하라는 뜻이다. 책 제목을 다시 보면 "이건 이런 내용에 관한 책이었지"라는 느낌이 들 정도면 충분하다.

일곱번째는 네번째와 관련이 있다. 친구를 많이 사귀는 것도 공부에 도움이 된다. 친구는 인생의 여러가지 면에서 나에게 도움을 줄 수 있는데, 그중에서 내가 모르는 것을 친구가 알고 있을 가능성이 있기 때문에 공부에도 도움이 된다. 이것은 친구가 많아질수록 내가 얻을 수 있는 지식의 범위도 확장되는 것이라고 생각하면 된다. 물론 나 역시 친구가 내게 무언가를 물어봤을 때 성실하게 대답해줄 의무를 가진다는 점은 잊지 말자.

당신이 타고난 천재가 될 수는 없겠지만, 노력하면 천재 비슷한 정도는 될지도 모른다.

물론, 난 이 글이 당신에게 어떤 영향을 미칠지에 대해서 전혀 보증을 못하는 바이다.

화요일, 12월 11, 2007

Recipe, Japan

:: Recipe
음... 너무 먹고 싶다... =)

http://baby.goo.ne.jp/member/ninshin/recipe/15/index.html

Stainless Steel Jewelry, Japan

:: 예쁘다... :)
http://www.inakanohanaya.jp

[CV][IP] Microsoft Photosynth Technology Preview

오래된 내용인데, 2007년이 가기 전에 blog 게시물 개수를 늘려야 하기에... ^^;

:: Microsoft Photosynth Technology Preview
http://labs.live.com/photosynth/view.html?collection=sanmarco/index1.sxs

good ~!

Linux Assembly Code

Linux Assembly Code

글쓴이 : 이호 (i@flyduck.com)
최신 글이 있는 곳 : http://linuxkernel.net/

v0.1.1 2000년 4월 8일
v0.1.0 2000년 3월 28일

차례

* 0. 서문
* 1. GAS와 AT&T 문법
* 2. Inline Assembly
* A. Reference


0. 서문
이 문서는 리눅스에서 사용하는 어셈블리 문법에 대해서 (특히 x86에서) 간략히 요약한 글입니다. 리눅스에서 사용하는 어셈블리 코드는 Intel/Microsoft에서 사용하는 어셈블리 코드와 차이를 보입니다. 문법도 서로 틀릴 뿐만 아니라, C 코드 중간에 사용하는 inline 어셈블리 코드의 사용법도 많은 차이를 보입니다. 이 글은 리눅스에서 어셈블리 코드를 작성하는 법이 아니라, 이미 어셈블리어에 대해서 어느정도 지식이 있다는 가정하에, 리눅스 용으로 작성된 어셈블리 코드를 읽는 법을 다룹니다.

1장. GAS와 AT&T 문법에서는 GAS에서 사용하는 AT&T 문법이 Intel/Microsoft에서 사용하는 문법과 어떤 차이가 있는지를 설명합니다. AT&T 문법은 Intel에서 사용하는 문법과 많은 차이를 보이는데, 여기서 비롯되는 혼동을 없애려고 합니다. 이 장은 인텔에서 사용하는 어셈블리어(Microsoft의 Macro Assembler나 Borland의 Turbo Assembler 등)를 알고 있다면 많은 도움이 될 것입니다. 2장 Inline Assembly는 C 코드내에서 어셈블리 코드를 사용하는 방법에 대한 글입니다. 커널 코드에서 CPU에 의존적인 부분들의 상당수는 inline 어셈블리 코드로 작성되어 있는데, 어셈블리어를 알고 있다고 하더라도 처음 접하는 경우 이 코드는 암호처럼 보이기도 합니다. 이 장은 GCC의 inline assembly 형식에 낯선 사람들이 이를 이해하는데 도움이 될 것입니다.

이 문서는 Linux Assembly HOWTO 문서와 Brennen's Guide to Inline Assembly, DJGPP QuickASM Programming Guide, GCC Manual, GAS Manual에 있는 내용을 요약 정리한 것입니다. 여기 등장하는 예제들 역시 앞의 글에 있는 코드들을 많이 참조한 것입니다. 되도록 꼭 필요한 내용을 중심으로 간결하게 정리하려고 하였으며, 더 자세한 설명을 바란다면 A. Reference에 나오는 문서들을 보시기 바랍니다. 실제 CPU 명령어에 대해서는 각 CPU 제조회사에서 제공하는 매뉴얼을 참조하시기 바랍니다. x86에서 사용하는 명령어는 Intel 홈페이지에 있는 (Intel Architecture Software Developer's Manual)이나 (Pentium Processor Family Developer's Guide)에 자세히 나와 있습니다.

이 글에서 잘못된 점을 발견하시거나 보충할 점이 있으면 언제든지 편지를 보내주십시오. 질문 및 대답은 홈페이지에 있는 게시판을 이용하시기 바랍니다. 그럼 리눅스를 공부하시는 분들께 도움이 되길 바랍니다.


1. GAS와 AT&T 문법
GAS는 GNU Assembler로서 GCC와 함께 쌍으로 사용되는 어셈블러이다. (인텔용 리눅스에는 GAS - /usr/bin/as - 외에도 AS86 - /usr/bin/as86 - 이라는 어셈블러가 있다. 이것은 x86용 16-bit 어셈블러로서, 여기서 사용하는 문법은 AT&T 문법이 아니라 Intel/Microsoft 형태에 가까운 것이다. 이 어셈블러는 커널의 boot loader같이 x86의 실제모드(real mode)에서 수행되는 16-bit 어셈블리 코드를 어셈블링하는데 사용한다. 이에 반해 GAS는 x86에만 국한되지 않는 32-bit 어셈블러이다.) GAS는 32-bit UNIX Compiler를 위해 만들어졌으므로, UNIX에서 일반적으로 사용되는 AT&T 문법을 따른다. 이 문법은 Intel/Microsoft에서 사용하는 문법과는 많이 다르다. 이를 비교해보면 :

* Register 이름 : 모든 레지스터 이름에는 %가 앞에 붙는다. 이는 레지스터와 다른 심볼들을 혼동하지 않게 하는 장점이 있다. 예를 들어 eax 레지스터를 나타낼 때 :

AT&T : %eax
Intel : eax

참고로 Intel 80386에는 다음과 같은 레지스터가 있다 :

o 일반 목적 register :
%eax (%ax, %ah, %al), %ebx (%bx, %bh, %bl), %ecx (%cx, %ch, %cl), %edx (%dx, %dh, %dl) : 32-bit, 16-bit, 8-bit로 사용가능
%esi (%si), %edi (%di), %ebp (%bp), %esp (%sp) : 32-bit, 16-bit로 사용가능
o segment (selector) register : %cs, %ds, %es, %fs, %gs, %ss
o flag register : (EFLAGS)
o instruction pointer : %eip
o processor control register : %cr0 - %cr4
o debug register : %db0 - %db7
o test register : %tr1 - %tr12
o floating point register stack : %st => %st(0) - %st(7)

* Operand 순서 : 원본(source)이 왼쪽, 목적지(destination)가 오른쪽에 위치한다. Intel 문법에서는 이와 반대로 되어 있다. 예를 들어 eax에서 ebx 레지스터로 데이터를 복사하는 것은 :

AT&T : movl %eax, %ebx
Intel : mov ebx, eax

* Operand 크기지정 : operand의 크기를 지정할 때 크기에 따라 b (byte), w (word), l (long) 접미사를 명령어에 붙인다. operand로 지정된 레지스터를 가지고 크기를 판단할 수 있을 때는 이를 생략할 수 있으며, 판단할 수 없는 경우 32-bit 연산으로 가정하게 된다. operand가 레지스터가 아니라 메모리인 경우는 반드시 접미사를 붙여야 한다. Intel에서는 byte ptr, word ptr, dword ptr 같은 지시자(specifier)를 사용하여 이를 나타낸다. 예를 들어 word크기의 foo 값을 bx로 복사하는 것은 :

AT&T : movw foo, %ax
Intel : mov ax, word ptr foo

이와 관련하여 AT&T와 Intel에서 사용하는 명령어들은 대부분 비슷하지만 몇가지 다른게 있다. sign extend 명령어와 zero extend 명령어는 조금 다른데, AT&T 문법에서는 extend 명령어에 원래의 크기와 확장할 크기를 지정하게 한다 :

movsSD (sign extend, Intel에서는 movsx)
movzSD (zero extend, Intel에서는 movzx)

여기서 S는 원래의 크기이고, D는 목적하는 크기이다. 예를 들어 ax를 ecx로 sign extend를 한다면 :

AT&T : movswl %ax, %ecx
Intel : movsx ecx, ax

또한 다음 변환함수에도 차이가 있다 :

cbtw (sign extend byte (%al) to word (%ax), Intel에서는 cbw)
cwtl (sign extend word (%ax) to long (%eax), Intel에서는 cwde)
cwtd (sign extend word (%ax) to long (%dx:%ax), Intel에서는 cwd)
cltd (sign extend dword (%eax) to quad (%edx:%eax), Intel에서는 cdq)

* 상수(constant)와 immediate 값 : 모든 상수와 immediate 값에는 $가 붙는다. 예를 들어 숫자 5는 $5라고 한다. 변수의 주소를 나타낼 때에도 앞에 $를 붙인다. 예를 들어 foo란 변수의 주소는 $foo이다. 그냥 foo라고 하면 변수의 값을 나타내게 된다. 숫자 0xd00d를 eax 레지스터로 복사하는 것은 :

AT&T : movl $0xd00d, %eax
Intel : mov eax, 0d000h

foo 변수의 주소를 eax 레지스터로 복사하는 것은 :

AT&T : movl $foo, %eax
Intel : mov eax, foo

foo의 값을 eax 레지스터로 복사하는 것은 :

AT&T : movl foo, %eax
Intel : mov eax, [foo]

* 메모리 참조 : 메모리 주소를 참조할데에는(indexing, indirection) AT&T와 Intel에서 표기법상 약간의 차이가 있다. base 주소와 index, scale, immediate 값이 주어졌을 때 :

AT&T : section:immed32(base, index, scale)
Intel : section:[base + index * scale + immed32]

이는 base + index * scale + immed32 주소를 나타내게 된다. 이들 모두를 반드시 지정해야 하는 것은 아니지만 immed32나 base 중의 하나는 반드시 지정해야 하며, 없는 항목은 비워두어도 된다. 주소 지정의 예로, eax 레지스터가 가리키는 주소의 값을 참조하는 경우 :

AT&T : (%eax)
Intel : [eax]

eax 레지스터에 변수(var)의 옵셋을 합한 주소를 참조하는 경우 :

AT&T : var(%eax)
Intel : [eax + var]

4바이트 단위로 된 정수 배열(int array[])의 eax번째 값을 참조하는 경우 (int array[eax]) :

AT&T : array(, %eax, 4)
Intel : [eax * 4 + array]

위 배열에서 ebx 인덱스에서 시작하여 eax번째 값을 참조하는 경우 (int array[ebx + eax]) :

AT&T : array(%ebx, %eax, 4)
Intel : [ebx + eax * 4 + array]

* jump/call/return : long jump나 long call에서는 다음과 같은 차이가 있다 :

AT&T : ljmp/lcall $section, $offset
Intel : jmp/call far section:offset

far retrun의 경우 :

AT&T : lret $stack-adjust
Intel : ret far stack-adjust

* 그밖에 : AT&T Assembler에서는 여러개의 section을 지원하지 않는다. UNIX 프로그램에서는 모든 프로그램이 하나의 section에 있다고 생각을 한다.


2. Inline Assembly
inline assembly는 high-level 언어로 된 코드 중간에 넣어서 사용하는 어셈블리 코드로, GCC에서 사용하는 inline assembly는 __asm__()안에 들어가며, 네가지 항목으로 이루어져 다음과 같은 형식으로 사용한다.

__asm__(어셈블리 문장 : 출력 : 입력 : 변경된 레지스터);

각 항목은 콜론(':')으로 구분되며, 어셈블리 문장은 반드시 들어가야 하지만, 뒤의 세 항목은 필요에 따라서 넣거나 생략할 수 있다. 각 항목은 다음과 같은 의미를 가진다.

* 어셈블리 문장 (assembly statement) : AT&T 형식으로 만들어진 어셈블리 코드로 "" 안에 넣어서 작성하며 각각의 줄은 newline으로 구분된다.
* 출력 (output) : 어셈블리 코드에서 출력용으로 사용하는 레지스터/메모리를 변수와 연결시켜준다. 여러개를 지정할 수 있으며 각 항목은 쉼표(',')로 구분된다. 각 항목은 "=g"(var)같은 형식을 가진다.
* 입력 (input) : 어셈블리 코드에서 입력으로 사용하는 레지스터/메모리를 변수와 연결시켜준다. 여러개를 지정할 수 있으며 각 항목은 쉼표(',')로 구분된다. 각 항목은 "g"(var)같은 형식을 가진다.
* 변경된 레지스터 (registers-modified 또는 clobbered regisers) : 어셈블리 코드에서 컴파일러가 모르는 사이에 바뀔 수 있는 레지스터의 목록을 기술한다. 각 항목은 "" 안에 들어가며, 여러개의 항목을 넣을 때에는 쉼표(',')로 구분한다. 메모리에 있는 변수의 값을 수정하는 경우 "memory"라고 기술해주어야 한다.

예제 코드를 보면 :

__asm__ ("pushl %eax\n"
"movl $1, %eax\n "
"popl %eax"
);

이 코드는 eax 레지스터를 저장하고 여기에 1을 입력했다가 eax 레지스터를 원래의 값으로 복구하는 코드이다. 여기서는 아무런 입력이나 출력이 없으며, 변경되는 레지스터도 없으므로 어셈블리 코드만 존재한다. 이제 i라는 변수를 하나 증가시키는 코드를 만들어보자.

int i = 0;

__asm__ ("pushl %%eax\n"
"movl %0, %%eax\n"
"addl $1, %%eax\n"
"movl %%eax, %0\n"
"popl %%eax"
: /* no output variable */
: "g" (i)
);

우선 이 코드에서 모든 레지스터 앞에 %가 두개가 붙어있는데, 입력이나 출력, 변경된 레지스터 중의 하나라도 기술을 하는 경우, 레지스터 이름에는 %를 하나가 아니라 두개를 붙여야 한다. 이는 내부에서 입출력을 나타내는데 %0, %1 같은 기호를 사용하는데, 이것과 혼동되는 것을 막기 위해서이다. 이 코드에서는 출력이 없으므로 출력은 비워 두었다. 입력에는 "g"(i)라고 적혀 있는데, 이는 i라는 변수를 %0과 연결시켜주는 역할을 한다. 즉 코드내에서 %0은 변수 i와 같은 의미로 사용된다. 따옴표 안에 있는 것은 변수와 어떤것이 연결되는지를 말하는데 g는 이경우 컴파일러가 알아서 레지스터에 넣던지 메모리에 두던지 하라고 지시하는 것이다. 따옴표 안에는 다음과 같은 것을 지정할 수 있으며, 그 의미는 다음과 같다.

a eax
b ebx
c ecx
d edx
S esi
D edi
I 상수 (0에서 31) ("I"라고 사용하는게 아니라 "0" 처럼 숫자를 넣어서 사용)
q eax, ebx, ecx, edx 중 동적으로 할당된 레지스터
r eax, ebx, ecx, edx, esi, edi 중 동적으로 할당된 레지스터
g eax, ebx, ecx, edx 또는 메모리에 있는 변수. 컴파일러가 선택
A eax 와 edx를 결합한 64-bit 정수
m 정적 메모리 위치
f floating point register

입력에서 여러개를 기술하면, 기술한 순서대로 차례로 %0, %1, ... 의 이름을 갖게 된다. 출력에도 무언가 기술한 경우, 출력부터 시작하여 차례로 %0, %1 ... 의 이름을 갖는다. 출력이 있는 예로 :

int x = 1, x_times_5;

__asm__ ("leal (%1, %1, 4), %0"
: "=r" (x_times_5)
: "r" (x)
);

위 코드는 x라는 변수를 다섯배 곱하여 x_times_5에 저장하는 것이다. (%1, %1, 4) = %1 + %1 * 4 = %1 * 5, lea는 주소를 저장하라는 명령이므로 %0에 %1을 다섯배한 값이 들어가게 된다. 여기서는 결과를 저장해야 하므로 출력에 "=r"(x_times_5)라고 출력되는 변수를 지정하였다. 따옴표안에 =가 들어가는 것은 출력임을 나타내기 위해서이다. 이 코드를 조금 수정하여 x를 다섯배 곱하여 자기 자신인 x에 이 값을 넣는다면 :

__asm__ ("leal (%1,%1,4), %0"
: "=r" (x)
: "0" (x)
);

여기서 입력에 "0"이라고 숫자로 썼는데, 이는 앞에서 지시한 것을 다시 가리키는 경우로, 여기서는 %0과 똑같은 것이라는 것을 말한다. 순서에 따라 출력 "=r"은 %0, 입력 "0"은 %1이 되는데, 자기 자신에게 결과를 돌려주어야 하므로, 이 둘이 같은 것이라는 것을 나타내기 위해 %1은 "0"이라고 하여 %0과 같은 것이라고 지시해주는 것이다. 그래서 이 코드는 x를 다섯배를 곱하여 결과를 자기 자신에서 돌려주게 된다. 다음은 입출력을 같이 하는 예로 k = i + j를 한다면 :

int i = 1, j = 2, k;

__asm__ __volatile__ ("pushl %%eax\n"
"movl %1, %%eax\n"
"addl %2, %%eax\n"
"movl %%eax, %0\n"
"popl %%eax"
: "=g" (k)
: "g" (i), "g" (j)
);

순서에 따라 k = %0, i = %1, j = %2가 되고, %1 + %2를 %0에 저장하므로 k에는 i + j 값이 들어가게 된다. 여기서 __asm__ 다음에 __volatile__이라는 지시자가 있는데, 이는 이 코드를 지정한 위치에 그대로 두라는 것이다. 컴파일러는 최적화(optimization)를 하는 과정에서 코드의 위치를 옮길 수 있는데 이를 막는 것이다.

#define rep_movsl(src, dest, numwords) \
__asm__ __volatile__ ( \
"cld\n" \
"rep\n" \
"movsl" \
: \
: "S" (src), "D" (dest), "c" (numwords) \
: "%ecx", "%esi", "%edi" \
)

위 코드는 src에서 dest로 지정한 길이만큼 복사하는 것이다 (C의 memcpy() 함수). 이 코드를 실행하면 ecx, esi, edi 레지스터가 바뀌므로, 마지막에 변경된 레지스터 목록에 이 세개를 지정해주었다.

#define rep_stosl(value, dest, numwords) \
__asm__ __volatile__ ( \
"cld\n" \
"rep\n" \
"stosl" \
: \
: "a" (value), "D" (dest), "c" (numwords) \
: "%ecx", "%edi" \
)

위 코드는 이전 코드와 비슷한 예로 dest의 지정한 길이만큼을 지정한 value로 설정하는 것이다 (C의 memset() 함수). inline assembly 안에서 local label도 사용할 수 있는데, 지정하는 방법은 일반 label과 똑같이 하지만, 이를 참조할 때에는 label이 앞에 있느냐, 뒤에 있느냐에 따라 b (backward), f (forward) 접미사를 붙여준다.

__asm__ ("" \
"0:\n" \
"jmp 1f\n" \ # jump to label 1: forward
"1:\n"\
"jmp 0b" \ # jump to label 0: backward
);


A. Reference

* Linux Assembly HOWTO :
o 영문판 : http://linuxdoc.org/HOWTO/Assembly-HOWTO.html
o 한글판 : http://kldp.org/HOWTO/Assembly-HOWTO
* Brennen's Guide to Inline Assembly :
o http://www.delorie.com/djgpp/doc/brennan/brennan_att_inline_djgpp.html
* DJGPP QuickASM Programming Guide :
o http://www.castle.net/~avly/djasm.html
* x86 Assembly Language FAQ :
o http://www.faqs.org/faqs/assembly-language/x86/
* GCC Manual (GCC Inline Assembly) :
o http://gcc.gnu.org/onlinedocs/gcc_toc.html
* GAS Manual :
o http://www.gnu.org/manual/gas-2.9.1/as.html

INTEL to AT&T ASM

아나, 꼭 안보다가 볼 때 ... 이런...
GCC Inline Assemble code 도 올려놔야겠다... -_-; 에이씨...

[INTEL]
mov ax, word[msg]
mov ax, 1
mov ah, 1
mov word [ds:si], ax
mov ah, 'a'
int 0x13
jmp 0x1000:0000

msg db 'M'
msg db 0x10, 0x20
dw 0aa55h
times 100 db 0

[AT&T]
movw msg, %ax
movw $1, %ax
movb $1, %ah
movw %ax, %ds:(%si)
movb $'a' , ah
int $int13
ljmp $0x1000, $0

msg: .byte 'M'
msg: .byte 0x10, 0x20
.word 0xaa55
.space 100, 0

일기 (2007.12.11)

:: 23억 기부하고 아내한테 3만원 빌려쓰는 남자

<배한성의 아주 특별한 인터뷰> 고학 제자 위해 23억 기부, 경희대 한승무 교수
http://news.msn.co.kr/article/read.html?cate_code=1200&article_id=200712101808591200

▶ 미래에 대한 계획이다보니 계획에 차질이 생기는 경우도 생길 수 있지 않을까요?
물론 제가 건강이 안 받쳐 주어서 일을 못하는 경우를 제외하고는 그런 경우가 없고요.
제가 우스운 표현으로 “수류탄에 왜들 놀랠까? 핵폭탄도 남아 있는데...” 하는 말을 하는데요.
이것은 제가 확보된 부분에 대한 것에 불과하기 때문에 앞으로 지켜보시면 더 놀라실 일들이 많을 겁니다.

▶ 힘들고 불투명한 미래에 대해 힘들어하는 젊은이들에게 어떤 말을 해주고 싶으신가요?
저는 ‘열정’이라는 단어와 ‘믿음’이라는 단어를 제일 좋아하는데요.
어려운 학생들을 보면 정말 사방이 다 막혀도 희망의 끈을 붙들고 열정을 가지고 된다는
강한 의지만 갖고 있다면 길이 열린다고 봅니다. 저도 다 막혀서 길이 안 보였을 때도
정말 열심히 그런 마음으로 사니까 길이 열리고 더 좋은 길이 나타났기 때문에,
어떤 환경에 있든지 조금 더 그런 열정으로 최선을 다한다면 지금은 앞이 안보여도
미래에 좋은 길들이 다 열릴 겁니다.


...
부럽다...
내가 비록 지금은 경제적으로 능력이 안되지만,
언젠가는 나도 내가 잘 되면 이렇게 남을 도와 주며 살고 싶다...

Regards,
godmode2k