<?xml version="1.0" encoding="utf-8" ?>
<?xml-stylesheet href="http://rss.egloos.com/style/blog.xsl" type="text/xsl" media="screen"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>
	<title>My keyboard</title>
	<link>http://busang.egloos.com</link>
	<description>GNU,LINUX,UBUNTU,GOOGLE</description>
	<language>ko</language>
	<pubDate>Sun, 14 Jun 2009 12:09:04 GMT</pubDate>
	<generator>Egloos</generator>
	<image>
		<title>My keyboard</title>
		<url>http://pds7.egloos.com/logo/200802/10/59/f0010059.jpg</url>
		<link>http://busang.egloos.com</link>
		<width>80</width>
		<height>76</height>
		<description>GNU,LINUX,UBUNTU,GOOGLE</description>
	</image>
  	<item>
		<title><![CDATA[ pic 강좌 ]]> </title>
		<link>http://busang.egloos.com/1436614</link>
		<guid>http://busang.egloos.com/1436614</guid>
		<description>
			<![CDATA[ 
  <a href="http://song9063.kde.or.kr/phpBB3/viewforum.php?f=5">http://song9063.kde.or.kr/phpBB3/viewforum.php?f=5</a><br><br><br/><br/>tag : <a href="/tag/pic" rel="tag">pic</a>,&nbsp;<a href="/tag/pic16f" rel="tag">pic16f</a>,&nbsp;<a href="/tag/pic16f84" rel="tag">pic16f84</a>,&nbsp;<a href="/tag/pic16f844" rel="tag">pic16f844</a>			 ]]> 
		</description>
		<category>pic</category>
		<category>pic</category>
		<category>pic16f</category>
		<category>pic16f84</category>
		<category>pic16f844</category>

		<comments>http://busang.egloos.com/1436614#comments</comments>
		<pubDate>Sun, 14 Jun 2009 12:09:04 GMT</pubDate>
		<dc:creator>송진영</dc:creator>
	</item>
	<item>
		<title><![CDATA[ avr usb isp USBasp 사용법 ]]> </title>
		<link>http://busang.egloos.com/1436611</link>
		<guid>http://busang.egloos.com/1436611</guid>
		<description>
			<![CDATA[ 
  공개 avr usb isp인 USBasp 사용법 한글 설명서<br><br><br><br><a href="http://song9063.kde.or.kr/phpBB3/viewtopic.php?f=2&amp;t=3">http://song9063.kde.or.kr/phpBB3/viewtopic.php?f=2&amp;t=3</a><br/><br/>tag : <a href="/tag/avr" rel="tag">avr</a>,&nbsp;<a href="/tag/avrisp" rel="tag">avrisp</a>,&nbsp;<a href="/tag/usbisp" rel="tag">usbisp</a>,&nbsp;<a href="/tag/usbasp" rel="tag">usbasp</a>,&nbsp;<a href="/tag/isp" rel="tag">isp</a>			 ]]> 
		</description>
		<category>avr</category>
		<category>avr</category>
		<category>avrisp</category>
		<category>usbisp</category>
		<category>usbasp</category>
		<category>isp</category>

		<comments>http://busang.egloos.com/1436611#comments</comments>
		<pubDate>Sun, 14 Jun 2009 12:08:07 GMT</pubDate>
		<dc:creator>송진영</dc:creator>
	</item>
	<item>
		<title><![CDATA[ win-avr 사용 방법( 초보자 대상 강좌 ) ]]> </title>
		<link>http://busang.egloos.com/1436604</link>
		<guid>http://busang.egloos.com/1436604</guid>
		<description>
			<![CDATA[ 
  <a href="http://song9063.kde.or.kr/phpBB3/viewtopic.php?f=2&amp;t=2">http://song9063.kde.or.kr/phpBB3/viewtopic.php?f=2&amp;t=2</a><br/><br/>tag : <a href="/tag/winavr" rel="tag">winavr</a>,&nbsp;<a href="/tag/winavr강좌" rel="tag">winavr강좌</a>,&nbsp;<a href="/tag/winavr사용법" rel="tag">winavr사용법</a>,&nbsp;<a href="/tag/avr" rel="tag">avr</a>,&nbsp;<a href="/tag/atmega" rel="tag">atmega</a>			 ]]> 
		</description>
		<category>avr</category>
		<category>winavr</category>
		<category>winavr강좌</category>
		<category>winavr사용법</category>
		<category>avr</category>
		<category>atmega</category>

		<comments>http://busang.egloos.com/1436604#comments</comments>
		<pubDate>Sun, 14 Jun 2009 12:06:47 GMT</pubDate>
		<dc:creator>송진영</dc:creator>
	</item>
	<item>
		<title><![CDATA[ [Assembly] 기본 어셈블리 언어 ]]> </title>
		<link>http://busang.egloos.com/1404397</link>
		<guid>http://busang.egloos.com/1404397</guid>
		<description>
			<![CDATA[ 
  원문 : http://www.drpaulcarter.com/pcasm/<br />
번역 : 송진영( caddsjy@gmail.com )<br />
<br />
<font size="4">2.1 정수 작업(Working with Integers)<br />
<br />
2.1.1 정수에 대한 설명<br />
<font size="2">&nbsp;정수는 2가지 형태로 표현합니다. : 부호가 없거나 부호가 있는 정수.<br />
&nbsp;부호가 없는 정수는( 양의 정수 ) 아주 똑바른 바이너리 방식입니다. 숫자 200을 1바이트의 부호없는 정수로 표현하면</font></font> 11001000( 16진수로&nbsp; C9 )이 됩니다.<br />
&nbsp;부호가 있는 정수(양의 정수 혹은 음의 정수)는 복잡한 방법으로 표현할 수 밖에 없습니다. 예를 들어 -56. +56은 00111000으로 표현해야하는데 종이위에 글로 표현할때는 -56을 -111000으로 적으면 되지만 메모리상에서는 이 -를 표현할 방법이 없습니다. 어떻게하면 마이너스 기호를 메모리에 기록할수 있을까요?<br />
&nbsp;컴퓨터 메모리에 부호를 기록하는 일반적인 3가지의 기술이 있습니다. 모든 방법들은 정수에 부호비트를 갖게 하는 것입니다. 양수이면 이 비트의 값이 0이고 만약 음수라면 이 비트의 값은 1이 됩니다.<br />
<br />
&nbsp; <span style="font-weight: bold;">Signed magnitude</span><br />
&nbsp;첫번째로<span style="font-style: italic;"> signed magnitude</span>라고 불리는 간단한 방법이 있습니다. 이 방식은 정수를 두 부분으로 표현합니다. 첫번째 부분은 부호비트로 두번째 부분은 정수의 크기를 나타냅니다. 56이라는 수는 <span style="text-decoration: underline;">0</span>0111000(맨 앞의 밑줄이 그려진 비트가 부호비트입니다.)으로 표현합니다. 그리고 -56은 <span style="text-decoration: underline;">1</span>0111000으로 표현합니다. 1 바이트로 표현할 수 있는 가장 큰값은 <span style="text-decoration: underline;">0</span>1111111 또는 +127이고 가장 작은 수는 <span style="text-decoration: underline;">1</span>111111 또는 -127입니다. 음수의 표현을 위해 부호비트가 사용됩니다. 이 방식은 쉽게 표현이 가능하지만 문제점을 가지고 있습니다. 첫번째로 두가지의 0의 표현이 생깁니다. +0(<span style="text-decoration: underline;">0</span>0000000)과 -0(<span style="text-decoration: underline;">1</span>0000000). 두번째로 일반 연산에서도 문제가 생깁니다. 만약 10에 -56을 더하면 10에서 56을 빼게되는데 CPU의 로직에서는 복잡해집니다.<br />
<br />
<br />
&nbsp;<span style="font-weight: bold;">One's complement</span> <span style="font-weight: bold;">(1의 보수 )</span><br />
&nbsp;두번째 방식으로 <span style="font-style: italic;">one's complement</span>라는 것이 있습니다. <br />
이 방식은 각각의 비트를 반전시키는 방법을 사용합니다. 예를 들어 <span style="text-decoration: underline;">0</span>0111000 (+56)의 1의 보수는 <span style="text-decoration: underline;">1</span>1000111이 됩니다. 1의 보수법은 1의 보수가 대응하는 음수값이 됩니다. 그러므로 -56은 <span style="text-decoration: underline;">1</span>1000111으로 표현됩니다. 첫번째 방식에서 0은 <span style="text-decoration: underline;">0</span>0000000(+0)과 <span style="text-decoration: underline;">1</span>1111111(-0)으로 2가지가 나타납니다. 1의 보수또한 연산이 복잡합니다. <br />
&nbsp;2진수로 바꾸지않고 16진수로 1의 보수값을 찾는 방법이있습니다.&nbsp; hex값 F에서 숫자를 뺍니다.(또는 십진수 15에서) <br />
예를들어 +56은 hex로 38입니다. 이 수에서 1의 보수를 찾는 방법은 각 비트값들을 F에서 뺀값으로 바꾸면됩니다.<br />
F-3 = C, F-8=7이므로 0x38의 1의 보수값은 0xC7이 됩니다.<br />
<br />
<span style="font-weight: bold;">&nbsp;Two's complement (2의 보수)</span><br />
&nbsp;앞의 두가지 방식은 예전의 컴퓨터에서 사용했던 방식들입니다. 현대의 컴퓨터는 2의 보수로 표현됩니다. 2의 보수는 두가지 단계로 계산해낼 수 있습니다.<br />
<ol><li>&nbsp;숫자의 1의 보수를 계산한다.</li><li>&nbsp;1번 결과 같에 1을 더한다.</li></ol>아래에 <span style="text-decoration: underline;">0</span>0111000(56)의 2의 보수를 구하는 예가 있습니다. 먼저 56의 1의 보수를 구합니다. : <span style="text-decoration: underline;">1</span>1000111. 그리고 여기에 1을 더합니다.<br />
<span style="text-decoration: underline;"></span><blockquote><span style="text-decoration: underline;">1</span>1000111<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1<br />
--------------------<br />
<span style="text-decoration: underline;">1</span>1001000<br />
</blockquote><br />
&nbsp;2의 보수 표현 방식으로는 2의 보수에 해당하는 음수를 계산 할 수 있습니다. 그러므로 <span style="text-decoration: underline;">1</span>1001000은&nbsp; -56의 2의 보수로 표현됩니다. 한번 더 반복하면 원래의 숫자로 돌아옵니다. 2의 보수로 계산된 <span style="text-decoration: underline;">1</span>1001000의 1의 보수를 다시 구하면<br />
<span style="text-decoration: underline;">0</span>0110111이 되고 여기에 1을 더하면 <span style="text-decoration: underline;">0</span>0111000이 됩니다.<br />
<br />
<br />
<br />
&nbsp;2의 보수에서 덧셈을 할 경우 가장 왼쪽 비트에는 캐리가 발생하게 됩니다. 이 캐리는 사용되지 않습니다.<br />
컴퓨터의 모든 데이터들은 어느정도의 고정된 크기를 가지고 있다는 것을 기억하세요. ( 비트의 수.. ) 이 점은 2의 보수 표현에 있어서 중요한 부분입니다. 예를 들어 0의 2의 보수를 계산하면 0이 됩니다.<br />
<span style="text-decoration: underline;">0</span>0000000의 1의 보수는 <span style="text-decoration: underline;">1</span>1111111이고 여기에 1을 더하면 캐리(자리올림)가 발생하는데 이 캐리를 무시하면 <span style="text-decoration: underline;">0</span>0000000만 남게 되므로 0이 됩니다.<br />
<br />
<span style="text-decoration: underline;"></span><blockquote><span style="text-decoration: underline;">1</span>1111111<br />
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1<br />
---------------------<br />
c <span style="text-decoration: underline;">0</span>0000000</blockquote><br />
&nbsp;c가 위치한 곳에 캐리가 발생합니다. (후에 여기에서 발생한 캐리를 확인하는 방법을 보여줄 것입니다. 그러나 결과값에는 캐리를 저장하지 않습니다. ) 그러므로 2의 보수의 표현에서 0은 항상 1가지만 존재합니다. 이 것은 2의 보수를 사용함으로써 앞의 방식들보다 간단하게 수학연산을 가능하게 했습니다.<br />
&nbsp;2의 보수 표현법을 사용하여 -128~+127까지의 부호있는 수를 표현가능합니다. 표 2.1에서 가능한 몇가지의 수를 나타내고 있습니다.<br />
<br />
----표 2.1 : 2의 보수 표현----<br />
수&nbsp;&nbsp;&nbsp; | hex<br />
0&nbsp;&nbsp;&nbsp;&nbsp; | 00<br />
1&nbsp;&nbsp;&nbsp;&nbsp; | 01<br />
127&nbsp; | 7F<br />
-128 | 80<br />
-127 | 81<br />
-2&nbsp;&nbsp;&nbsp; | FE<br />
-1&nbsp;&nbsp;&nbsp; | FF<br />
----------------------------<br />
<br />
만약 16비트를 사용하게 되면 부호있는 수는 -32,768~32,767까지 표현가능 합니다. +32,767은 0x7FFF이고 -32768은 0x8000으로 표현합니다. -128은 0xFF80, 그리고 -1은 0xFFFF가 됩니다. 32비트에서 2의 보수로 표현가능한 수의 범위는 -20억에서 +20억까지 가능합니다.<br />
&nbsp;CPU는 byte에 대해 (또는 word나 double word) 아는 바가 없습니다. 어셈블리도 고급언어에서 가지고있는 타입에 대해서도 모릅니다. 데이타가 해석되는 것은 데이터가 사용되는 부분의 명령에 의존적입니다. hex값 FF가 부호있는 -1인지 부호없는 +255로 해석될지는 프로그래머에게 달려있습니다. C언어는 signed와 unsigned 정수 형이 정이되어져 있습니다. 이 것으로 C컴파일러는 명령어가 사용하는 데이터를 정확하게 알 수 있도록 해줍니다.<br />
&nbsp;<br />
<br />
<br />
<font size="4">&nbsp;2.1.2 Sign extension</font><br />
&nbsp;어셈블리에서 모든 데이터는 크기를 가지고 있습니다. <br />
<br />
&nbsp;<span style="font-weight: bold;">데이터의 크기 줄이기</span><br />
&nbsp; 데이터의 크기를 줄이기 위해서 간단하게 데이터에서 중요한 비트만 남기고 삭제하면 됩니다. <br />
아래에 예가 있습니다.<br />
<br />
<blockquote>mov ax, 0034h&nbsp; ; ax = 52( 16비트로 저장됩니다. )<br />
mov cl, al&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; cl = ax의 하위 8비트 값이 기록됩니다.</blockquote>&nbsp;만약 숫자가 작은 크기에서는 정확히 표현을 할 수 없다면 크기를 줄이는 작업을 할 수가 없습니다. 예를 들어 만약 AX의 값이 0134h였다면 위의 코드에서 CL에는 34h가 될 것입니다. 이 동작은 signed나 unsigned 모두 동작은 합니다. signed번호로 가정하고 만약 AX의 값이 FFFFh( word로 -1 )라면 CL의 값은 FFh( byte로 -1 )가 될 것입니다. 하지만 AX가 unsigned 일때는 이 값이 정확하지 않게 될 것입니다!<br />
&nbsp;부호없는 숫자를 위한 규칙은 삭제될 모든 비트가 0일때만 정확하게 계산됩니다. 부호있는 숫자의 경우 삭제될 숫자가 모두 1이거나 모두 0일 경우에 정확하게 계산됩니다. 추가적으로 삭제될 비트와 삭제되지 않을 비트의 값이 동일한경우에도 같은 값을 가지게 됩니다. 이 비트는 작은 값의 새로운 부호 비트가 될 것입니다. 이 점은 원본의 부호비트와 동일하게  하기 위한 중요한 내용입니다.<br />
<br />
<br />
<span style="font-weight: bold;">데이터의 크기 늘리기</span><br />
&nbsp;데이터의 크기를 늘리는 것은 줄이는 것보다 더 복잡합니다. hex byte FF를 word로 늘렸다면 어떤 word값으로 바뀌었을까요?<br />
이것은 FF를 해석하는 것에 따라 달라집니다. 만약 FF가 부호없는 바이트라면(10진수 255) word값 00FF로 될 것입니다. 그러나 만약 부호있는 바이트라면( 십진수 -1 ) 이 값은 FFFF가 될 것입니다.<br />
&nbsp;일반적으로 부호없는 수를 확장하면 확장되는 새로운 수들은 0으로 채워집니다. 그러므로 FF는 00FF가 됩니다. 그러나 부호있는 수를 확장하기 위해서 부호비트를 확장해야만 한다. 이 뜻은 새로운 비트는 부호비트의 사본이된다. FF의 부호비트가 1이므로 새로운&nbsp; 비트들은 반드시 1이 되게 되며 FFFF로 만들어진다. 만약 부호있는 5A의 경우는 확장되면 005A가 된다.<br />
<br />
&nbsp;80386이 수의 확장을 위해 제공하는 몇개의 명령어가 있습니다. 컴퓨터는 숫자가 signed 인지 unsigned인지 모른다는 점을 기억하세요. 이 것은 프로그래머가 정확한 명령을 사용하여 결정됩니다.<br />
&nbsp;부호없는 수를 위해서 mov명령어를 사용하여 상위비트를 0으로 만듭니다. 예를 들어 AL의 바이트를 확장하여 부호없는 AX의 word로 바꿔보겠습니다. :<br />
<blockquote>&nbsp;mov ah, 0&nbsp; ; 상위 8비트들을 0으로 만듭니다.</blockquote>&nbsp;하지만 mov명령어를 사용하여 AX의 unsigned word값을 unsigned double word인 EAX로 바꾸는 것은 불가능합니다. 왜 안될까요? 이유는 mov명령어로는 EAX의 상위 16비트들을 정의할 수 있는 방법이 없기 때문입니다. 80386은 이 문제를 해결하기 위해 MOVZX라는 새로운 명령어를 제공합니다. 이 명령어는 2개의 오퍼랜드들을 가집니다. 첫번째 오퍼랜드는 목적지(destination)이고 반드시 16또는 32비트의 레지스터여야 합니다. 두번째 오퍼랜드는 소스(source)로써 8또는 16비트의 레지스터나 byte 또는 메모리의 word값이여야 합니다.<br />
&nbsp;또 다른 제약사항으로는 destination은 반드시 source보다 커야합니다.(많은 명령어들은 source와 destination은 같은 크기를 요구합니다.)<br />
아래에 몇가지 예가 있습니다. :<br />
&nbsp;<blockquote>&nbsp;movzx eax, ax&nbsp; ; ax를 eax로 확장<br />
&nbsp;movzx eax, al&nbsp;&nbsp; ; al을 eax로 확장<br />
&nbsp;movzx ax, al ; al을 ax로 확장<br />
&nbsp;movxz ebx, ax ; ax를 ebx로 확장</blockquote><br />
&nbsp;signed 숫자를 위해서는 MOV 명령어를 쓰는것이 쉽지 않습니다. 8086은 signed 수를 확장하기 위한 몇가지 명령어들을 제공합니다. <span style="font-weight: bold;">CBW( Convert Byte to Word ) </span>명령어는 부호있는 AL을 AX레지스터로 확장하는 명령입니다. 오퍼랜드는 암묵적입니다. <span style="font-weight: bold;">CWD( Convert Word to Double )</span> 명령어는 AX를 DX:AX로 확장합니다. DX:AX의 뜻은 DX를 32비트 레지스터의 상위 16비트로, AX레지스터를 하위 비트들로 사용한다는 의미를 가집니다. ( 8086은 어떠한 32비트 레지스터도 없다는 것을 기억하십시요! ) 80386은 몇개의 새로운 명령어들이 추가되었습니다. <span style="font-weight: bold;">CWDE( Convert Word to Double word Extended )</span>명령은 AX를 EAX로 확장하고, <span style="font-weight: bold;">CDQ( Convert Double word to Quad word)</span> 명령어는 부호있는 EAX를 EDX:EAX형태의 64비트로 확장하는 명령입니다.<br />
&nbsp;마지막으로 <span style="font-weight: bold;">MOVSX</span> 명령어는 <span style="font-weight: bold;">MOVZX</span>명령과 비슷한 기능을 가지며 signed 숫자를 위한 명령입니다.<br />
<br />
<br />
<span style="font-weight: bold;">&nbsp;Application to C programming</span><br />
&nbsp; unsigned와 signed정수를 확장하는 일은 C 언어에서도 발생합니다. C언어의 변수들은 signed나 unsigned( int는 signed )로 선언됩니다. Figure 2.1의 코드의 3번째줄에서는 <span style="font-weight: bold;">MOVZX</span>명령을 사용하게 되며 unsigned 값을 확장하는 것입니다. 그러나 4번째 줄은 <span style="font-weight: bold;">MOVSX</span>를 사용하여 signed 규칙을 사용한 것입니다.<br />
<br />
----Figure 2.1-----<br />
unsigned char uchar = 0xFF;<br />
signed char schar = 0xFF;<br />
int a = (int)uchar;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* a = 255 ( 0x000000FF ) */<br />
int a = (int)schar;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* b = -1 ( 0xFFFFFFFF) */<br />
-----------------------<br />
<br />
--------Figure 2.2-------<br />
char ch;<br />
while( (ch = fgetc( fp ) ) != EOF ){<br />
&nbsp;/* do something with ch */<br />
}<br />
-------------------------<br />
<br />
<br />
시간상 다음에 계속....<br />
<br />
<br/><br/>tag : <a href="/tag/assembly" rel="tag">assembly</a>,&nbsp;<a href="/tag/GNU" rel="tag">GNU</a>,&nbsp;<a href="/tag/LINUX" rel="tag">LINUX</a>,&nbsp;<a href="/tag/bash" rel="tag">bash</a>,&nbsp;<a href="/tag/GOOGLE" rel="tag">GOOGLE</a>			 ]]> 
		</description>
		<category>Assembly</category>
		<category>assembly</category>
		<category>GNU</category>
		<category>LINUX</category>
		<category>bash</category>
		<category>GOOGLE</category>

		<comments>http://busang.egloos.com/1404397#comments</comments>
		<pubDate>Fri, 15 May 2009 10:22:31 GMT</pubDate>
		<dc:creator>송진영</dc:creator>
	</item>
	<item>
		<title><![CDATA[ [Assembly] 1. 소개..이어서... ]]> </title>
		<link>http://busang.egloos.com/1404396</link>
		<guid>http://busang.egloos.com/1404396</guid>
		<description>
			<![CDATA[ 
  원문 : http://www.drpaulcarter.com/pcasm/<br />
번역 : 송진영( caddsjy@gmail.com )<br />
<br />
<font size="4">1.3.6 입력과 출력( Input and Output )</font><br />
&nbsp;입출력은 시스템에 의존적입니다. 이 것은 시스템의 하드웨어와 인터페이싱을 해야합니다. C언어와 같은 고급언어에서는 표준 라이브러리에서 기본적인 루틴을 제공하여 간단하고 편리하게 I/O 프로그램을 할 수가 있습니다.&nbsp; 어셈블리 언어에서는 제공되는 표준 라이브러리가 없습니다. 어셈블리에서는 OS가 제공하는 저수준의 루틴을 이용하거나 하드웨어에 직접 접근하게 됩니다.<br />
&nbsp;어셈블리코드는 표준 C라이브러리의 I/O루틴을 사용할 수 가 있다. 하지만 C언어에서 사용되는 루틴으로 정보를 전달해야하는 규칙을 알아야 한다. 이 규칙은 여기서 설명하기에는 복잡하다.( 후에 다룰 것이다. ) 간단한 입출력 처리를 위해서 C의 복잡한 규칙을 숨기고 좀더 간단한 인터페이스를 가진 제작자만의 루틴을 개발한다. <span style="font-weight: bold;">표 1.4</span>에 제공되는 루틴들이 나열되어있다. read루틴을 제외한 모든 루틴들은 모든 레지스터들의 값을 유지하고 있다. 이 루핀들은 <span style="font-weight: bold;">EAX</span> 레지스터의 값을 변경한다. 이 루틴들을 사용하기 위해서 어셈블러가 루틴을 사용하기 위해 필요한 정보들이 기록된 파일을 포함하여야 한다. <span style="font-weight: bold;">NASM</span>에서 파일을 포함하기 위해서는 <span style="font-weight: bold;">%include </span>전처리 지시어를 사용하면 된다. 아래에 제작자의 I/O루틴 파일을 포함하는 예가 있다.<br />
<br />
<blockquote>%include "asm_io.inc"</blockquote>위 예에서 사용된 asm_io.inc파일은 asm_io라는 목적파일이 필요하다. 이 예제 코드는 아래의 웹페이지에서 다운 받을 수 있다.<br />
http://www.drpaulcarter.com/pcasm<br />
<br />
---표 1.4 어셈블리 I/O 루틴들----<br />
print_int&nbsp;&nbsp; EAX에 기록된 정수값을 스크린에 출력한다.<br />
print_char&nbsp; AL에 기록된 ASCII 문자를 스크린에 출력한다.<br />
print_string EAX에 기록된 주소에서 시작되는 문자열을 스크린에 출력한다.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 문자열은 C언어 형식을 사용한다( 널 문자로 끝나는.. )<br />
print_nl&nbsp;&nbsp; 스크린에 줄바꿈 문자를 출력한다.<br />
read_int&nbsp;&nbsp; 키보드에서 입력된 숫자를 읽고 EAX레지스터에 기록한다.<br />
read_char&nbsp; 키보드에서 한 문자를 입력 받고 ASCII코드를 EAX레지스터에 기록한다.<br />
-----------------------------------------<br />
<br />
<br />
<font size="4">1.3.7 디버깅(Debugging)</font><br />
&nbsp;제작자의 라이브러리 또한 프로그램을 디버깅하는데 유용한 몇가지의 루틴들을 포함하고 있습니다. 디버깅 루틴들은 상태를 수정할 수없이 컴퓨터의 상태에 대한 정보를 출력하게 됩니다. 이 루틴들은 CPU의 현재 상태를 저장하는 Macro이며 서브루틴을 호출하게 됩니다. Macro는 위에서 언급 되었던 asm_io.inc파일에 정의 되어져 있습니다. Macro는 일반적인 명령어처럼 사용됩니다. 매크로들의 오퍼랜드들은 콤마로 구분됩니다.<br />
&nbsp;아래는 4가지의 디버깅용 루틴들에 대해 설명되어져있습니다. 레지스터,메모리,스택등의 값들을 보여주게 됩니다.<br />
<br />
<ul><li>dump_regs&nbsp; 이 매크로는 레지스터들의 값을 컴퓨터의<span style="font-weight: bold;"> stdout</span>(예: 스크린) 출력합니다.(16진수로). 또한 FLAGS레지스터(Chapter2에서 설명합니다.)에 셋팅된 비트 값들을 출력합니다. 만약 zero플래그가 1이면 ZF가 출력되고, 이것이 0이면 출력되지 않습니다. 이 것은 하나의 정수 인자를 가지며 보기 좋게 출력되는 값입니다. 이 것은 dump_regs 명령과 출력이 구별되도록 사용합니다.</li><li>dump_mem&nbsp; 이 매크로는 메모리의 영역의 값(16진수)을 출력하고 또한 아스키 문자들도 출력합니다. 이 것은 세개의 콤마로 구분된 인자를 가지고 있습니다. 첫번째 인자는 정수이며 Label을 출력할 것인지를 정합니다.( dump_regs의 인자와 비슷합니다. ) 두번째 인자는 어드레스를 출력할지, 마지막 인자는 어드레스 다음에 16-byte paragraph의 수를 보여줄지를 지정합니다. 메모리는 요청된 주소 이전의 첫번째 paragraph영역을 시작으로 표시될 것입니다.</li><li>dump_stack&nbsp; 이 매크로는 CPU 스택의 값들을 출력합니다.( 스택에 대해서는 Chapter4에서 다루도록 합니다. ) 스택은 double word의 구조로 출력됩니다.&nbsp; 콤마로 구분되는 3개의 인자를 가집니다. 첫 번째 인자는 label을 출력할지에 대한 정수( dump_regs와 같다. ), 두번째는 EBP레지스터가 고정한 어드레스 아래의 double word의 수, 세번째 인자는 EBP내의 어드레스 위의 double word의 수를 설정합니다.</li><li>dump_math&nbsp; 이 매크로는 수학연산의 레지스터의 값을 출력합니다. 하나의 인자를 가지며 dump_regs의 인자와 같이 Label을 출력할지를 결정합니다.</li></ul><br />
<br />
<br />
<font size="4">1.4 프로그램 작성하기(Creating a Program)</font><br />
&nbsp;어셈블리 언어로 독립적으로 작동하는 프로그램을 만들어보겠습니다. 고급언어는 어셈블리보다 매우 쉽게 프로그램을 작성할수 있다. 또한 어셈블리러 작성된 프로그램은 다른 플랫폼으로 이식하기가 매우 어렵다. 사실 모든 곳에서 어셈블리가 특별하게 사용되고 있다.<br />
&nbsp;왜 어셈블리를 공부해야만 할까요?<br />
&nbsp;1. 가끔 어셈블리로 작성된 코드는 컴파일러가 생성한 코드보다 작고 빠르다.<br />
&nbsp;2. 어셈블리는 시스템의 하드웨어에 직접적으로 접근이 가능하다. 고급언어에서는 이것이 어렵거나 불가능하다.<br />
&nbsp;3. 어셈블리를 공부함으로써 컴퓨터가 어떻게 작동되는지 구조에대해 쉽게 이해할 수 있다.<br />
&nbsp;4. 어셈블리를 공부함으로써 C와 같은 고급언어와 컴파일러의 구조에대해 더 심도 있게 이해할 수 있다.<br />
<br />
<br />
<br />
<font size="4">1.4.1 첫번째 프로그램( First program )</font><br />
&nbsp;Figure 1.6의 simple C driver프로그램은 asm_main이라는 함수를 호출하는 간단한 프로그램입니다. 이것은 실제로 어셈블리로 작성될 것입니다. C driver루틴을 사용하면 몇가지의 이점이 있습니다. 첫번째는 C 시스템은 보호모드에서 동작합니다. 모든 세그먼트들과 대응하는 세그먼트 레지스터들은 C에 의해서 초기화 될것입니다. 어셈블리 코드는 이것들에 대한 신경을 쓰지 않아도 됩니다.<br />
두번째로 C라이브러리 또한 어셈블리코드에서 사용이 가능합니다. 저작자의 I/O루틴들도 이 장점을 가지고 있습니다. 이 입출력 루틴들은 C의 I/O루틴을 사용합니다.(printf와 같은,.) 아래에 간단한 어셈블리 프로그램이 있습니다.<br />
<br />
===Figure 1.6 : driver.c code===<br />
int main()<br />
{<br />
&nbsp; int ret_status;<br />
&nbsp; ret_status = asm_main();<br />
&nbsp; return ret_status;<br />
}<br />
=========================<br />
<br />
===first.asm===<br />
; file : first.asm<br />
; 첫 번째 어셈블리 프로그램. 이 프로그램은 두개의 정수를 입력받고<br />
; 입력된 두 수의 합을 출력합니다.<br />
;<br />
; djgpp를 사용하여 실행파일을 만드는 법:<br />
; nasm -f coff first.asm<br />
; gcc -o first first.o driver.c asm_io.o<br />
<br />
%include "asm_io.inc"<br />
;<br />
; .data 세그먼트내에 데이터 초기화 코드를 넣습니다.<br />
segment .data<br />
;<br />
; 여기 label들은 출력될 문자열을 참조하게 됩니다.<br />
;<br />
prompt1 db "Enter a number : " , 0 ; 널 문자열로 종료되야한다는 것을 기억하십시요!<br />
prompt2 db "Enter another number : " , 0<br />
outmsg1 db "You entered ", 0<br />
outmsg2 db " and ", 0<br />
outmsg3 db ", the sum of these is " , 0<br />
<br />
;<br />
; .bss 세그먼트에는 초기화되지 않는 데이터를 넣습니다.<br />
segment .bss<br />
;<br />
; 이 곳의 Label들은 입력된 값들을 저장할 double word 값을 참조합니다.<br />
;<br />
input1 resd 1<br />
input2 resd 1<br />
<br />
;<br />
; code는 .text 세그먼트에 입력합니다.<br />
;<br />
segment .text<br />
&nbsp;&nbsp; global _asm_main<br />
_asm_main:<br />
&nbsp; enter 0,0&nbsp; ; 셋업 루틴<br />
&nbsp; pusha<br />
<br />
&nbsp; mov eax, prompt1 ; prompt출력<br />
&nbsp; call print_string<br />
<br />
&nbsp; call read_int&nbsp; ; 정수값 읽어오기<br />
&nbsp; mov [input1], eax ; input1에 저장하기<br />
<br />
&nbsp; mov eax, prompt2 ; 프롬프트 출력<br />
&nbsp; call print_string<br />
<br />
&nbsp; call read_int ; 정수값 읽어오기<br />
&nbsp; mov [input2], eax ; input2에 저장하기<br />
<br />
&nbsp; mov eax, [input1] ; eax = input1<br />
&nbsp; add eax, [input2] ; eax += input2<br />
&nbsp; mov ebx, eax ; ebx = eax<br />
<br />
&nbsp; dump_regs 1&nbsp; ; 레지스터의 값 출력<br />
&nbsp; dump_mem 2, outmsg1, 1 ; 메모리 값 출력<br />
<br />
;<br />
; 결과 메세지를 단계적으로 출력합니다.<br />
;<br />
&nbsp; mov eax, outmsg1<br />
&nbsp; call print_string ; 첫번째 메세지 출력<br />
&nbsp; mov eax, [input1] <br />
&nbsp; call print_int ; input1 출력<br />
&nbsp; mov eax, outmsg2<br />
&nbsp; call print_string ; 두번째 메세지 출력<br />
&nbsp; mov eax, [input2]<br />
&nbsp; call print_int ; input2 출력<br />
&nbsp; mov eax, outmsg3<br />
&nbsp; call print_string ; 세번째 메세지 출력<br />
&nbsp; mov eax, ebx<br />
&nbsp; call print_int ; 합한 결과(ebx) 출력<br />
&nbsp; call print_nl ; 줄바꿈 문자 출력<br />
<br />
&nbsp; popa<br />
&nbsp; mov eax, 0 ; C로 리턴<br />
&nbsp; leave<br />
&nbsp; ret<br />
-------------------------------<br />
<br />
&nbsp;13번째 줄의 섹션은 프로그램에서 사용하는 데이터가 저장될 메모리를 정의합니다.(<span style="font-weight: bold;">.data</span>) 이 세그먼트에 정의되는 데이터들은 초기화된 상태로 정의해야합니다. 17~21번째 줄에 몇개의 문자열들이 선언되어져있습니다. C라이브러리를 통하여 출력될 것이고 반드시 null 문자로 끝나는 문자열이여야만 합니다. 0과 '0'은 다르다는 것에 주의하십시요.<br />
<br />
&nbsp; 초기화되지 않은 데이터는 <span style="font-weight: bold;">.bss</span> 세그먼트내에 선언해야 합니다. 이 세그먼트의 이름은 UNIX기반의 어셈블러에서 <span style="font-style: italic;">"block started by symbol"</span>이라는 것에서 따온 것입니다. 스택 세그먼트 또한 그렇습니다. 이것에 대해서는 후에 설명할 것입니다.<br />
<br />
&nbsp; 코드 세그먼트의 명칭은 <span style="font-weight: bold;">.text</span> 입니다. 이 것은 명령어들의 위치를 가리킵니다. 언더바(_)로 시작되는 메인 루틴(38번 라인)의 Label이 명령어들의 시작 Label을 가리킵니다. 이 것은 <span style="font-style: italic;">C calling convention</span>의 일부분입니다. 이 관례는 코드를 컴파일 할 때 사용되는 C규칙입니다. 이 것은 C와 어셈블리가 상호 호환성을 가지기 위한 매우 중요한 점입니다. <br />
<br />
&nbsp;37번째 줄의 <span style="font-weight: bold;">global</span> 지시문은 어셈블러에게 <span style="font-weight: bold;">_asm_main</span>이라는 전역 Label을 만들도록 지시합니다.<br />
C와는 다르게, Label은 기본적으로 내부적으로만(<span style="font-style: italic;">internal scope</span>) 사용할 수 있습니다. 이 뜻은 오로지 동일한 모듈 내의 코드만 사용할 수 있는 지역 Label이라는 것입니다. <span style="font-weight: bold;">global</span> 지시자는 지정한 label(또는 label들)을 외부(<span style="font-style: italic;">external scope</span>)에서도 사용할 수 있게 합니다. 이 Label의 형식은 프로그램내의 어떠한 모듈에서도 접근할 수 있게 됩니다. asm_io 모듈은 print_int라는 전역 레이블을 선언하였기에 first.asm 모듈에서도 사용할 수 있게 된 것입니다.<br />
<br />
<br />
&nbsp;<br />
<font size="4">1.4.2 컴파일러 의존성( Compiler dependencies )</font><br />
&nbsp;위의 어셈블리 코드는 GNU(http://www.fsf.org)기반의 DJGPP C/C++ 컴파일러(http://www.delorie.com/djgpp) 기준으로 작성되었습니다. 이 컴파일러는 인터넷상에서 무료로 구할 수 있습니다. 386기반의 PC또는 DOS, Windows95/98 또는 NT에서 잘 동작합니다. 이 컴파일러는 COFF(Common Object File Format)포맷의 목적파일을 사용합니다. 이 형식으로 어셈블하기 위해서는 <span style="font-weight: bold;">nasm</span>에<span style="font-weight: bold;"> -f coff</span>옵션을 지정합니다.(위 코드의 주석문에도 나와있습니다.) 어셈블후의 목적파일의 확장자는 <span style="font-weight: bold;">o</span>입니다.<br />
&nbsp;리눅스 C컴파일러 또한 GNU 컴파일러와 동일합니다. 위의 코드를 Linux상에서 변환시 간단하게 37,38번째라인의 언더바 접두사를 삭제하면 됩니다. 리눅스는 ELF(Excutable and Linkable Format) 형식의 목적코드를 사용합니다. 리눅스에서는<span style="font-weight: bold;"> -f elf</span>옵션으로 어셈블합니다. 출력된 목적코드의 확장자는 <span style="font-weight: bold;">o</span>입니다.<br />
&nbsp;볼랜드 C/C++는 또 다른 대중적인 컴파일러입니다. 이 컴파일러는 마이크로소프트 OMF포맷을 목적코드의 형식으로 사용합니다.<span style="font-weight: bold;"> -f obj</span> 옵션을 사용하면 됩니다. OMF 형식은 특별한 segment 지시자를 사용합니다. 13번째 줄의 data segment를 아래처럼 수정해야합니다.<br />
&nbsp;segment _DATA public align=4 class=DATA use32<br />
<br />
26번째 줄의 bss segment도 아래와 같이 수정합니다.<br />
&nbsp;segment _BSS public align=4 class=BSS use32<br />
<br />
36번째 줄의 text&nbsp; segment도 아래와 같이 수정합니다.<br />
&nbsp;segment _TEXT public align=1 class=CODE use32<br />
<br />
&nbsp;36번째줄 이전에 아래와 같이 새로운 줄을 추가해야합니다.<br />
&nbsp;group DGROUP _BSS _DATA<br />
<br />
&nbsp;마이크로소프트 C/C++ 컴파일러는 OMF형식 또는 Win32형식의 목적 파일 모두 사용가능합니다.( 만약 OMF형식이 주어지면 내부족으로 WIN32형식의 정보로 변환됩니다. ) Win32 형식은 segment들이 DJGPP와 Linux형태로 선언된 것을 허용합니다.<br />
<span style="font-weight: bold;">-f win32</span>옵션으로 이 기능을 사용가능합니다. 이 형식의 목적코드의 확장자는<span style="font-weight: bold;"> obj</span>입니다.<br />
<br />
<br />
<br />
<br />
<font size="4">1.4.3 코드 어셈블하기( Assembling the code )</font><br />
&nbsp;첫번째 단계는 코드를 어셈블하는 것입니다. 커맨드라인 상에서 아래와 같이 입력하세요 :<br />
&nbsp;<blockquote>nasm -f <span style="font-style: italic;">object-format</span> first.asm</blockquote>&nbsp;위 명령에서 object-format이라는 문자열은 사용하시는 C컴파일러의 맞게 수정하셔서 입력하십시요.<br />
(elf, coff, obj, win32)<br />
<br />
<br />
<br />
<font size="4"><br />
1.4.4 C 코드 컴파일하기(Compiling the C code)</font><br />
&nbsp;C컴파일러로 driver.c 파일을 컴파일하세요. 만약 DJGPP를 사용하신다면 아래와 같이 컴파일하세요 :<br />
<blockquote>gcc -c driver.c</blockquote>&nbsp;-c옵션은 링크는 아직 하지 않고 오로지 컴파일만 한다는 의미입니다. Linux,Borland 그리고 Microsoft컴파일러에서도<br />
동일한 옵션으로 동작합니다.<br />
<br />
<br />
<br />
<br />
<font size="4">1.4.5 목적파일들 링크하기(Linking the object files)</font><br />
&nbsp;링크작업은 기계코드와 목적파일내의 데이터들 그리고 라이브러리 파일들을 연결하여 실행가능한 파일을 생성하는 것입니다.<br />
아래에서 이 작업을 보여줍니다.<br />
&nbsp;C코드를 실행하기 위해서는 표준 C라이브러리와 특수한<span style="font-style: italic;"> startup code</span>가 필요합니다. 그것은 C컴파일러가 정확한 파라메터로 링커를 호출하는 것을 쉽게하고 링커를 직접 호출하게 합니다. 예를 들어 DJGPP를 사용하여 첫번째 프로그램을 링크하는 것은 아래와 같습니다. :<br />
<blockquote>gcc -o first driver.o first.o asm_io.o</blockquote><br />
&nbsp;이렇게 하면 윈도우에서는 first.exe, 리눅스에서는 first라는 실행파일이 생성됩니다.<br />
&nbsp;볼랜드 컴파일러에서는 아래와 같이 링크합니다.<br />
<blockquote>bcc32 first.obj driver.obj asm_io.obj</blockquote>볼랜드 컴파일러는 파일 목록중 첫번째 파일의 이름으로 실행파일의 이름을 생성합니다.<br />
위의 경우 첫번째 입력파일이 first.obj이므로 first.exe라는 실행파일을 생성하게 됩니다.<br />
<br />
&nbsp;컴파일과 링크를 한번에 수행할 수 있습니다.:<br />
<blockquote>gcc -o first <span style="font-style: italic; font-weight: bold;">driver.c</span> first.o asm_io.o</blockquote>gcc는 driver.c를 컴파일 한 뒤에 링크를 수행할 것입니다.<br />
<br />
<br />
<br />
<font size="4">1.4.6 어셈블리 리스팅파일의 이해(Understanding an assembly listing file)</font><br />
&nbsp;nasm에서 <span style="font-weight: bold;">-l l</span><span style="font-style: italic; font-weight: bold;">isting-file</span><span style="font-weight: bold;"> </span>옵션을 사용하면 nasm은 주어진 이름의 리스팅 파일을 생성합니다. 이 파일은 코드가 어떻게 어셈블되었는지를 보여줍니다. 아래에 17,18번째 줄의(data 세그먼트내의) 코드에 대한 리스팅파일 내용입니다.(리스팅파일내의 줄번호는 원본 소스파일의 줄번호와 다를 수 있습니다.)<br />
<br />
<blockquote>48 00000000 456E7465722061206E- prompt1 db "Enter a number: ", 0<br />
49 00000009 756D6265723A2000 <br />
50 00000011 456E74657220616E6F- prompt2 db "Enter another number: ", 0<br />
51 0000001A 74686572206E756D62- <br />
52 00000023 65723A2000 </blockquote>&nbsp;<br />
&nbsp;각 줄의 첫 번째 컬럼에는 줄번호, 두번째 컬럼에는 세그먼트내의 데이터의 오프셋 값(16진수)을 나타냅니다.<br />
세번째 컬럼은 raw hex값이 기록되어져 있습니다. 이 경우에 hex데이터와 ASCII코드가 일치합니다. 마지막으로 소스파일상의 텍스트를 보여줍니다.두번째 컬럼의 오프셋 목록들은 실제적인 오프셋과 다릅니다. 각각의 모듈은 데이터 세그먼트(그리고 다른 세그먼트들도)내의 label들을 각각 가지고 잇습니다. 링크 단계에서 (1.4.5섹션을 참고하세요) 모든 데이터 세그먼트 label 선언들이 하나의 data세그먼트로 합쳐집니다. 새로운 마지막 오프셋은 링커에서 계산된 값이됩니다.<br />
&nbsp;아래에 리스팅파일의 text세그먼트 섹션의 일부분입니다.(소스파일의 54~56번째줄) <br />
<br />
<blockquote>94 0000002C A1[00000000] mov eax, [input1]<br />
95 00000031 0305[04000000] add eax, [input2]<br />
96 00000037 89C3 mov ebx, eax</blockquote>&nbsp;세번째 컬럼에서는 어셈블리가 생성한 기계코드입니다. 종종 최종 코드를 아직 생성할수 없을 때가 있습니다. 예를 들어 94번째 라인의<span style="font-weight: bold;"> input1</span>에 대한 offset(또는 어드레스)는 코드가 링킹되기 전까지는 알수가 없습니다. 어셈블러는 <span style="font-weight: bold;">mov</span>명령에대한 op-code를 생성할 수 잇습니다.(리스팅의 A1) 그러나 아직은 정확한 값을 계산할 수 없으므로 사각 괄호안에 오프셋이 기록됩니다. 이 경우는 임시로 0의 offset이 입력됩니다. <span style="font-weight: bold;">input1</span>은 소스파일의 시작부분 bss세그먼트내에 위치해있기 때문입니다. <span style="font-weight: bold;">input1</span>이 bss세그먼트의 제일 처음 지점에 있다는 것을 기억하십시요. 코드가 링크되었을 때 링커는 정확한 위치의 오프셋을 입력할 것입니다. 96번째 줄과 같은 다른 명령어들은 어떠한 label들도 참조하지 않습니다. 이런 것들은 어셈블러가 완성된 기계코드를 생성할 수가 있습니다.<br />
<br />
&nbsp;<span style="font-weight: bold;">Big and Little Endian에 대한 설명</span><br />
&nbsp; 만약 95번째 줄 기계코드의 사각괄호 안의 오프셋값은 독특합니다. <span style="font-weight: bold;">input2</span> 레이블은 offset4에 위치합니다.(이 파일내에 정의되어져있습니다.)&nbsp; 하지만 메모리내의 오프셋값이 00000004가 아닌 04000000으로 되어져있습니다. 왜일까요? 여러 프로세서들은 다중바이트 정수들을 특별한 순서로 메모리에 기록합니다. 수를 기록하는 두가지의 대중적인 방식으로 <span style="font-weight: bold;">big endian</span>과<span style="font-weight: bold;"> little endian</span>이 있습니다.<span style="font-weight: bold;"> Big endian</span>은 상위 바이트가 먼저 기록되고 다음으로 그다음 큰 바이트가 기록되는 방식입니다. 예를들어 dword 00000004은 4개의 바이트로 00 00 00 04순서로 기록됩니다. IBM구조와 대부분의 RISC 프로세서 그리고 모토롤라의 모든 프로세서들은 <span style="font-weight: bold;">big endian</span>을 사용합니다. 그러나 Intel기반의 프로세서들은 <span style="font-weight: bold;">little endian</span>방식을 사용합니다. 00000004값이 메모리에 저장될 때는 04 00 00 00으로 기록됩니다. 이 형식은 CPU에 내장되어있으므로 변경할 수가 없습니다. 일반적으로 프로그래머는 이 형식을 사용하는 것에 대해서 걱정할 필요가 없습니다. 하지만 아래의 상황들에서는 매우 중요합니다.<br />
<ol><li>&nbsp;서로 다른 컴퓨터간에 바이너리데이터를 전송할 때( 네트워크를 통한 파일 전송 등)</li><li>&nbsp;바이너리 데이터를 메모리에 기록하고 바이트들을 개별적으로 읽거나 그 반대의 상황일 때</li></ol>&nbsp;엔디안은 배열 요소의 순서에는 적용되지 않습니다. 첫번째 배열의 요소는 항상 낮은 주소를 갖습니다. 문자열에도 동일하게 적용됩니다. <br />
<br />
<br />
<br />
<font size="4">1.5 Skeleton File</font><br />
&nbsp;Figure 1.7은 어셈블리 프로그램을 작성하기 위한 시작점으로 사용하는 skeleton 파일을 보여줍니다.<br />
어셈블리 프로그램의 가장 기본적인 골격 구조만을 가진 코드입니다.<br />
&nbsp;<br />
=====Figure 1.7 Skeleton Program=====<br />
%include "asm_io.inc"<br />
segment .data<br />
;<br />
; 초기화되는 데이터를 이 곳에 선언합니다.<br />
;<br />
<br />
segment .bss<br />
;<br />
; 초기화 되지 않는 데이터를 이 곳에 선언합니다.<br />
;<br />
<br />
segment .text<br />
&nbsp;&nbsp;&nbsp;&nbsp; global _asm_main<br />
_asm_main:<br />
&nbsp;&nbsp;&nbsp;&nbsp; enter 0, 0&nbsp; ; setup routine<br />
&nbsp;&nbsp;&nbsp;&nbsp; pusha<br />
<br />
;<br />
; 코드는 text세그먼트에 기록됩니다. 이 주석문의 앞 또는 뒤의 <br />
; 코드는 수정해서는 안됩니다.<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp; popa<br />
&nbsp;&nbsp;&nbsp;&nbsp; mov eax, 0<br />
&nbsp;&nbsp;&nbsp;&nbsp; leave<br />
&nbsp;&nbsp;&nbsp;&nbsp; ret<br />
-------------------------<br />
<br />
<br />
<br />
<br />
<br/><br/>tag : <a href="/tag/assembly" rel="tag">assembly</a>,&nbsp;<a href="/tag/pcassembly" rel="tag">pcassembly</a>,&nbsp;<a href="/tag/linux" rel="tag">linux</a>,&nbsp;<a href="/tag/linuxassembly" rel="tag">linuxassembly</a>,&nbsp;<a href="/tag/GNU" rel="tag">GNU</a>			 ]]> 
		</description>
		<category>Assembly</category>
		<category>assembly</category>
		<category>pcassembly</category>
		<category>linux</category>
		<category>linuxassembly</category>
		<category>GNU</category>

		<comments>http://busang.egloos.com/1404396#comments</comments>
		<pubDate>Fri, 15 May 2009 10:21:13 GMT</pubDate>
		<dc:creator>송진영</dc:creator>
	</item>
	<item>
		<title><![CDATA[ [Assembly Language] 1. 소개..  ]]> </title>
		<link>http://busang.egloos.com/1404200</link>
		<guid>http://busang.egloos.com/1404200</guid>
		<description>
			<![CDATA[ 
  원문 : http://www.drpaulcarter.com/pcasm/<br />
번역 : 송진영( caddsjy@gmail.com )<br />
<br />
<font size="4">1.3.1 기계언어( Machine Language )</font><br />
&nbsp;모든 CPU들은 그들만의 언어(기계어)를 가지고 있다. 기계 명령어는 byte형태로 메모리에 기록된다.<br />
각각의 명령어들은 Operation code 또는 줄여서 opcode라고 불리는 고유한 숫자 코드로 이루어져 있다.&nbsp; 80x86 프로세서의 명령어들은 크기가 다양하다. opcode는 항상 명령어의 맨 앞에 위치한다. 또한 많은 명령어들은 명령에 사용될 데이터(상수나 주소)를 포함하고 있다.<br />
&nbsp;기계언어로 직접 프로그램을 작성하는 것은 매우 어렵다. 숫자로만 이루어진 코드를 사람이 읽고 분석하는 것은 매우 짜증날 만한 일이다. 예를들어 EAX와 EBX레지스터의 값들을 더한 결과를 EAX 레지스터에 기록하는 명령은 아래와 같은 Hex코드로 이루어진다.<br />
<br />
<blockquote style="font-weight: bold;">&nbsp;03 C3</blockquote><br />
&nbsp;위와 같이 hex로만 이루어진 코드를 분석하는 것은 아주 어렵다. 다행히도 assembler라는 언어를 통하여 좀 더 편하게 작업이 가능하다.<br />
<br />
<font size="4"><br />
<br />
1.3.2 어셈블리 언어 (Assembly language )</font><br />
&nbsp;어셈블리어는 text형태로 기록되어져 있다.( 고급언어와 같은.. ) 각 어셈블리 명령어는 1개의 기계언어로 표현된다. 예를 들어 위 <span style="font-style: italic;">1.3.1 기계언어</span>의 예를 어셈블리로 작성하면 아래와 같다.<br />
<blockquote style="font-weight: bold;">add eax, ebx</blockquote><blockquote></blockquote>&nbsp;기계어와 비교하면 어셈블리어의 명령은 아주 읽기가 쉽다. add라는 단어는 덧셈 명령의 니모닉(mnemonic)이다. 일반적인 어셈블리 명령의 형태는 아래와 같다. :<br />
<blockquote style="font-style: italic;">&nbsp;mnemonic operand(s)</blockquote>&nbsp;Assembler는 어셈블리 명령들이 기록된 텍스트 파일을 읽어서 기계언어로 변환한다. <span style="font-style: italic;">Compiler</span>는 고급언어에서 유사한 역할을 한다. 어셈블러는 컴파일러와 비교하면 매우 단순하다. 모든 어셈블리언어의 명령어는 1개의 기계명령과 직접적으로 연관된다. 하지만 고급언어에서 한개의 명령어는 하나 이상의 기계명령이 사용될 수도 있다.<br />
&nbsp;어셈블리언어와 고급언어들과의 또 다른 중요한 차이점은 모든 CPU마다 다른 기계명령어를 가지고있기 때문에 어셈블리 언어 또한 CPU마다 다르게 작성된다. 어셈블리로 작성된 프로그램을 다른 아키텍쳐의 컴퓨터로 이식하는 것은 고급언어와 비교하여 매우 어렵다.<br />
&nbsp;이 책의 예제들은 Netwide Assembler(줄여서 NASM)를 기준으로 작성되어졌다. NASM은 인터넷에서 무료로 구할 수 있다. <br />
다른 어셈블러로는 마이크로소프트사의 MASM, 볼랜드사의 TASM등이 있으며 모두 문법에 차이가 있다.<br />
<br />
<br />
<br />
<font size="4">1.3.3 명령어 (Instruction operands)</font><br />
&nbsp;기계코드 명령어는 다양한 숫자와 형식의 명령어들로 이루어져있다. 각 명령어들은 한정된 수의 오퍼랜드들을 가진다.(0~3개..)<br />
오퍼랜드들의 종류로는 아래와 같다 :<br />
<ul><li>&nbsp;<span style="font-weight: bold;">registor</span> : CPU의 레지스터를 직접적으로 참조하게 된다.</li><li>&nbsp;<span style="font-weight: bold;">memory</span> : 메모리상의 Data를 참조한다. 레지스터의 값을 사용하거나 상수가 될 수 있다. 메모리의 주소는 항상 세그먼트의 시작에서 부터의 offset값이 된다.</li><li><span style="font-weight: bold;">immediate</span> : 고정된 값, data세그먼트가아닌 명령내에 직접 저장된 값이다.</li><li><span style="font-weight: bold;">implied</span> : 이 오퍼랜드는 명시적으로 보여지지는 않는다. 예를들어 증분명령어는 레지스터나 메모리의 값에 1을 더하게 된다. 이 1이라는 값이 implied가 된다.(c언어에서 변수명++과 같은.. )</li></ul><br />
<br />
<font size="4">1.3.4 기본 명령들(Basic instructions)</font><br />
&nbsp;가장 기본적인 명령은 <span style="font-weight: bold;">MOV</span> 명령이다. 이 명령어는 데이터를 다른 곳으로 이동시킨다.( 고급언어의 대입연산자와 같은 역할이다. )<br />
MOV 명령은 두개의 오퍼랜드를 가진다.<br />
<br />
<span style="font-style: italic;"></span><blockquote><span style="font-style: italic;">&nbsp;mov dest, src</span></blockquote>&nbsp;src의 데이터를 dest로 복사하게 된다. 이 명령어의 한가지 제약사항은 양쪽의 오퍼랜드들이 메모리 오퍼랜드가 아니여야한다.<br />
여러가지의 명령어를 사용하는데에 있어서 임의의 규칙이 있다. 또한 오퍼랜드들은 반드시 크기가 같아야한다. AX의 값은 BL에 저장될 수 없다.<br />
&nbsp;아래에 몇가지 예가 있다.( 세미콜론으로 시작되는 부분은 주석이다. )<br />
<br />
<blockquote>&nbsp;mov eax, 3 ; EAX레지스터에 3을 기록한다.(3은 immediate 오퍼랜드이다. )<br />
&nbsp;mov bx, ax; AX에 기록된 값을&nbsp; BX레지스터에 기록한다.</blockquote><br />
<br />
<br />
<span style="font-weight: bold;">&nbsp;ADD</span>명령은 정수의 덧셈에 사용된다.<br />
&nbsp;<br />
<blockquote>&nbsp;add eax, 4 ; eax = eax + 4<br />
&nbsp;add al, ah ; al = al + ah</blockquote><br />
<br />
<br />
<span style="font-weight: bold;">&nbsp;SUB</span>명령은 정수의 뺄셈에 사용된다.<br />
<br />
<blockquote>&nbsp;sub bx, 10 ; bx = bx - 10<br />
&nbsp;sub ebx, edi; ebx = ebx - edi</blockquote><br />
&nbsp;<br />
<br />
<span style="font-weight: bold;">INC</span>와 <span style="font-weight: bold;">DEC</span>명령은 값을 1증분하거나 감소시킨다. 1이라는 오퍼랜드가 implicit오퍼랜드이며 직접적으로 코드에 표기하지는 않는다.<br />
<br />
<blockquote>&nbsp;inc ecx&nbsp; ; ecx++<br />
&nbsp;dec dl&nbsp;&nbsp; ; dl--</blockquote><br />
<br />
<font size="4">1.3.5 지시어(Directives)</font><br />
&nbsp;지시어는 실제적으로 CPU가 명령을 수행하는 것이아니고 어셈블러에서 사용하는 인위적인 지시어이다. 기계언어로 변환되지 않는다. <br />
공통적으로 지시어가 사용되는 것은 아래와 같다. :<br />
<ul><li>&nbsp;상수의 정의</li><li>&nbsp;데이터가 저장된 메모리 정의</li><li>&nbsp;세그먼트의 메모리 그룹</li><li>&nbsp;포함할 외부 소스 코드</li><li>&nbsp;포함하는 외부 파일들 </li></ul>C언어의 전처리기처럼 사용된다. C언어의 전처리문과 비슷한것이 많다. <br />
C언어에서는 #으로 시작되지만 NASM에서는 %로 시작된다.<br />
<br />
<br />
<span style="font-weight: bold;">equ 지시어</span><br />
&nbsp;<span style="font-weight: bold;">equ</span> 지시어는 <span style="font-style: italic;">symbol</span>을 정의할 때 사용됩니다. 심볼들은 어셈블리 프로그램 내에서 사용될 상수에 이름을 부여한 것입니다.<br />
형태는 아래와 같습니다. :<br />
&nbsp;<blockquote><span style="font-style: italic;">symbol</span> <span style="font-weight: bold;">equ</span> <span style="font-style: italic;">value</span></blockquote>이미 정의된 심볼의 값은 재정의 될 수 없습니다.<br />
<br />
<br />
<span style="font-weight: bold;">%define 지시어</span><br />
&nbsp;이 지시어는 C언어의 #define지시어와 유사합니다. C에서와 같이 상수의 정의를 위해 주로 사용됩니다.<br />
<blockquote><br />
%define SIZE 100<br />
&nbsp;mov eax, SIZE</blockquote><br />
&nbsp;위의 코드는 SIZE라고 정의된 macro를 MOV명령에서 사용하는 예입니다. Macro는 심볼을 유연하게 사용할 수 있습니다.<br />
값을 재정의 할 수 있으며 좀 더 많은 상수 숫자를 사용할 수 있습니다.<br />
<br />
<br />
<span style="font-weight: bold;">Data 지시어</span><br />
&nbsp;Data 지시어는 메모리 공간에서 데이터 세그먼트를 정의할 때에 사용됩니다.<br />
&nbsp;두 가지 종류의 메모리 할당이 가능합니다. 첫번째로는 데이터공간 만을 정의하고 두번째로는 데이터 공간을 정의한 뒤에<br />
초기값을 지정하는 것입니다. 첫번째 방식에서는 RES<span style="font-style: italic;">X</span>지시어를 사용합니다. RES다음의 X문자는 저장될 객체의 크기를 나타내는 기호를 사용합니다. 아래 표 1.3에 사용가능한 기호들의 목록이 있습니다.<br />
<br />
------표 1.3 RES<span style="font-style: italic;">X</span>와 D<span style="font-style: italic;">X</span> 지시어에 사용되는 기호-----<br />
단위&nbsp;&nbsp;&nbsp; | 기호<br />
byte&nbsp;&nbsp;&nbsp;&nbsp; | B<br />
word&nbsp;&nbsp;&nbsp; | W<br />
double word | D<br />
quad word | Q<br />
ten bytes | T<br />
--------------------------------------------------------------<br />
&nbsp;두 번째 방식( 메모리 할당 후 초기값 지정.. )은 D<span style="font-style: italic;">X</span>지시어를 사용합니다. RES<span style="font-style: italic;">X</span>지시어와 마찬가지로 D다음의 <span style="font-style: italic;">X</span>문자는 데이터의 크기를 나타내는 표1.3의 기호들 중 하나가 사용됩니다.<br />
&nbsp; 일반적으로 메모리의 위치를 나타낼<span style="font-style: italic;"> label</span>을 사용합니다. Label은 코드내에서 메모리의 위치를 참조하기 쉬운 방법을 제공합니다. 아래에 몇가지 예제가 있습니다. :<br />
<br />
<blockquote>L1 db 0 ; L1이라는 Label, byte크기만큼을 가지고 0으로 초기화 됨<br />
L2 dw 1000 ; L2, word크기의 공간을 가지며 1000으로 초기화 됨<br />
L3 db 110101b ; 2진수 110101로 초기화된 byte(십진수로는 53)<br />
L4 db 12h ; 16진수 12로 초기화된 byte(십진수로 18 )<br />
L5 db 17o ; 8진수 17로 초기화된 byte(십진수로 15)<br />
L6 dd 1A92h ; 16진수 1A92로 초기화된 double word<br />
L7 resb 1 ; 1개의 초기화 되지 않은 byte<br />
L8 db "a" ; Ascii코드 A(65)로 초기화된 byte<br />
</blockquote><br />
&nbsp;큰따옴표나 작은따옴표는 동일한 효과를 가집니다. 연속적으로 정의된 데이터들은 메모리에 순차적으로 기록됩니다.<br />
위의 예에서 L2는 메모리상에서 L1바로 다음에 기록됩니다. <br />
<br />
<blockquote>L9 db 0, 1, 2, 3 ; 4 byte들로 정의됩니다.<br />
L10 db "w", "o", "r", 'd', 0 ; C언어의 문자열처럼 "word"를 정의합니다.<br />
L11 db 'word', 0 ; L10과 동일합니다.</blockquote><br />
&nbsp;<span style="font-weight: bold;">DD</span> 지시어는 정수나 단정도 부동 소수점(C언어의 float 자료형과 같은) 상수를 정의하는데 사용됩니다. 하지만<span style="font-weight: bold;"> DQ</span>는 오로지 배정도 부동소수점( double precision floating point ) 상수를 정의할 수만 있습니다.<br />
&nbsp;한 번에 많은 크기의 변수를 할당하기 위해서 <span style="font-weight: bold;">NASM</span>에서는 <span style="font-weight: bold;">TIMES</span>지시어가 유용하게 사용됩니다. 이 지시어는 오퍼랜드의 수 만큼 반복됩니다.<br />
<br />
<blockquote>&nbsp;L12 times 100 db 0&nbsp; ; db 0을 100개 만든것과 같습니다.<br />
&nbsp;L13 resw 100 ; word 100개를 위한 공간을 할당합니다.</blockquote><br />
Label들은 코드내에서 데이터의 위치를 참조하는데 사용한다는 것을 기억하십시요. Label은 두가지 방식으로 사용될 수 있습니다. 만약 Label이 그냥 사용되면 data의 주소(또는 offset)로 해석되고 만약 사각 괄호([])로 둘러쌓여 사용되면 이것은 주소상에 위치한 데이터로 해석됩니다. 다른 말로 표현한다면, 첫 번째는 데이터의 포인터로 사용되고 두 번째는 포인터가 가리키는 데이터로 말할 수 있습니다.(C언어에서 포인터를 나타내는 *문자와 같습니다, MASM이나 TASM에서는 다르게 사용됩니다.) 32비트 모드에서 주소는 32비트까지 지정이 가능합니다. 아래에 몇가지 예가 있습니다.<br />
<br />
<blockquote>mov al, [L1] ; L1의 값을 AL로 복사<br />
mov eax, L1 ; EAX = L1이 위치한 어드레스<br />
mov [L1], ah ; AH를 L1에 복사<br />
mov eax, [L6] ; L1의 double word값을 EAX에 복사<br />
add eax, [L6] ; EAX = EAX + L6의 double word값<br />
add [L6], eax; L6의 double word값 += EAX<br />
mov al, [L6] ; L6의 double word값의 첫번째 바이트를 AL로 복사</blockquote>&nbsp;위 예에서 7번째 줄의 예는 NASM만의 중요한 속성을 보여줍니다. 어셈블러는 lable이 참조하고 있는 데이터의 타입에 대해서는 조사하지 않습니다. 프로그래머가 Label을 정확하게 사용해야합니다. 이 점은 C언어의 포인터변수와 유사합니다. 한번 더 강조하면 포인터가 정확하게 사용되었는지는 검사하지 않습니다. 이 경우에 어셈블리는 C보다 더 많은 에러가 발생할 수 있습니다.<br />
&nbsp;<br />
&nbsp;아래 명령어를 예로 보면 :<br />
<blockquote>&nbsp;mov [L6], 1 ; L6에 1을 기록</blockquote><br />
&nbsp;이 문법은 operation size not specified 에러를 발생할 것입니다.<br />
왜냐하면 어셈블러는 1이라는 값이 byte형인지 word형인지 double word형인지 알 수 가 없기 때문입니다.<br />
이 문제를 해결하기 위해서는 size 지시어를 추가합니다. :<br />
<blockquote>&nbsp;mov dword [L6], 1 ; L6에 1을 기록합니다.</blockquote>위 명령어는 L6주소를 시작으로 double word 크기만큼의 메모리 공간에 1을 기록하라는 것을 나타냅니다.<br />
또 다른 크기를 지정하는 지시어들은 다음과 같습니다.<br />
<span style="font-weight: bold;">BYTE, WORD, QWORD, TWORD</span><br />
(TWORD는 메모리에 10byte 영역을 정의합니다. )<br />
<br />
<br />
<br />
<br />
<br/><br/>tag : <a href="/tag/pcassembly" rel="tag">pcassembly</a>,&nbsp;<a href="/tag/assembly" rel="tag">assembly</a>,&nbsp;<a href="/tag/assemblylanguage" rel="tag">assemblylanguage</a>			 ]]> 
		</description>
		<category>Assembly</category>
		<category>pcassembly</category>
		<category>assembly</category>
		<category>assemblylanguage</category>

		<comments>http://busang.egloos.com/1404200#comments</comments>
		<pubDate>Fri, 15 May 2009 05:55:57 GMT</pubDate>
		<dc:creator>송진영</dc:creator>
	</item>
	<item>
		<title><![CDATA[ Qt xml ]]> </title>
		<link>http://busang.egloos.com/889439</link>
		<guid>http://busang.egloos.com/889439</guid>
		<description>
			<![CDATA[ 
  Qt를 이용한 xml파싱하기에 대한 간단한 설명입니다.<br />
<br />
<a href="http://song9063.kde.or.kr/">http://song9063.kde.or.kr/</a><br />
<br/><br/>tag : <a href="/tag/qt" rel="tag">qt</a>,&nbsp;<a href="/tag/qtxml" rel="tag">qtxml</a>,&nbsp;<a href="/tag/qtdom" rel="tag">qtdom</a>,&nbsp;<a href="/tag/qtsax" rel="tag">qtsax</a>,&nbsp;<a href="/tag/sax" rel="tag">sax</a>,&nbsp;<a href="/tag/xml" rel="tag">xml</a>			 ]]> 
		</description>
		<category>Qt 프로그래밍 노트</category>
		<category>qt</category>
		<category>qtxml</category>
		<category>qtdom</category>
		<category>qtsax</category>
		<category>sax</category>
		<category>xml</category>

		<comments>http://busang.egloos.com/889439#comments</comments>
		<pubDate>Mon, 29 Sep 2008 10:42:06 GMT</pubDate>
		<dc:creator>송진영</dc:creator>
	</item>
	<item>
		<title><![CDATA[ emacs c++ 개발환경 구축.. ]]> </title>
		<link>http://busang.egloos.com/870041</link>
		<guid>http://busang.egloos.com/870041</guid>
		<description>
			<![CDATA[ 
  구글링, KLDP등에서 찾은 자료들을 모아봤습니다.<br />
<a href="http://song9063.kde.or.kr/tc/?/category/7">http://song9063.kde.or.kr/tc/?/category/7</a><br/><br/>tag : <a href="/tag/emacs" rel="tag">emacs</a>,&nbsp;<a href="/tag/emacs-snapshot" rel="tag">emacs-snapshot</a>,&nbsp;<a href="/tag/emacscpp" rel="tag">emacscpp</a>,&nbsp;<a href="/tag/gnu" rel="tag">gnu</a>			 ]]> 
		</description>
		<category>Gnu Tool 노트</category>
		<category>emacs</category>
		<category>emacs-snapshot</category>
		<category>emacscpp</category>
		<category>gnu</category>

		<comments>http://busang.egloos.com/870041#comments</comments>
		<pubDate>Thu, 25 Sep 2008 01:21:49 GMT</pubDate>
		<dc:creator>송진영</dc:creator>
	</item>
	<item>
		<title><![CDATA[ Qt에서 database 사용하기... ]]> </title>
		<link>http://busang.egloos.com/870035</link>
		<guid>http://busang.egloos.com/870035</guid>
		<description>
			<![CDATA[ 
  &nbsp;옮겨진 저의 새 블로그에 포스팅했고<br />
아래는 링크입니다.<br />
<br />
<a href="http://song9063.kde.or.kr/tc/?/category/8">http://song9063.kde.or.kr/tc/?/category/8</a><br/><br/>tag : <a href="/tag/Qtsql" rel="tag">Qtsql</a>,&nbsp;<a href="/tag/QtSqlDatabase" rel="tag">QtSqlDatabase</a>,&nbsp;<a href="/tag/Qtdatabase" rel="tag">Qtdatabase</a>,&nbsp;<a href="/tag/QtSqlquery" rel="tag">QtSqlquery</a>			 ]]> 
		</description>
		<category>Qt 프로그래밍 노트</category>
		<category>Qtsql</category>
		<category>QtSqlDatabase</category>
		<category>Qtdatabase</category>
		<category>QtSqlquery</category>

		<comments>http://busang.egloos.com/870035#comments</comments>
		<pubDate>Thu, 25 Sep 2008 01:20:01 GMT</pubDate>
		<dc:creator>송진영</dc:creator>
	</item>
	<item>
		<title><![CDATA[ Qt에서 custom Model을 만드는 방법.. ]]> </title>
		<link>http://busang.egloos.com/870029</link>
		<guid>http://busang.egloos.com/870029</guid>
		<description>
			<![CDATA[ 
  &nbsp;옮겨진 저의 새 블로그에 포스팅했고<br />
아래는 링크입니다.<br />
<br />
<a href="http://song9063.kde.or.kr/tc/?/category/8">http://song9063.kde.or.kr/tc/?/category/8</a><br />
<br/><br/>tag : <a href="/tag/qt" rel="tag">qt</a>,&nbsp;<a href="/tag/Qtdatabase" rel="tag">Qtdatabase</a>,&nbsp;<a href="/tag/QSql" rel="tag">QSql</a>,&nbsp;<a href="/tag/QSqlDatabase" rel="tag">QSqlDatabase</a>,&nbsp;<a href="/tag/QSqlQuery" rel="tag">QSqlQuery</a>,&nbsp;<a href="/tag/Qtsql" rel="tag">Qtsql</a>,&nbsp;<a href="/tag/QAbstractItemModel" rel="tag">QAbstractItemModel</a>,&nbsp;<a href="/tag/MVC" rel="tag">MVC</a>,&nbsp;<a href="/tag/Model" rel="tag">Model</a>,&nbsp;<a href="/tag/view" rel="tag">view</a>,&nbsp;<a href="/tag/QtMVC" rel="tag">QtMVC</a>			 ]]> 
		</description>
		<category>Qt 프로그래밍 노트</category>
		<category>qt</category>
		<category>Qtdatabase</category>
		<category>QSql</category>
		<category>QSqlDatabase</category>
		<category>QSqlQuery</category>
		<category>Qtsql</category>
		<category>QAbstractItemModel</category>
		<category>MVC</category>
		<category>Model</category>
		<category>view</category>
		<category>QtMVC</category>

		<comments>http://busang.egloos.com/870029#comments</comments>
		<pubDate>Thu, 25 Sep 2008 01:17:56 GMT</pubDate>
		<dc:creator>송진영</dc:creator>
	</item>
</channel>
</rss>
