Linux Assembly Code


±Û¾´ÀÌ : ÀÌÈ£ (i@flyduck.com)
ÃֽŠ±ÛÀÌ ÀÖ´Â °÷ : http://linux.flyduck.com/

v0.1.0 2000³â 3¿ù 28ÀÏ


Â÷·Ê


0. ¼­¹®

ÀÌ ¹®¼­´Â ¸®´ª½º¿¡¼­ »ç¿ëÇÏ´Â ¾î¼Àºí¸® ¹®¹ý¿¡ ´ëÇؼ­ (ƯÈ÷ x86¿¡¼­) °£·«È÷ ¿ä¾àÇÑ ±ÛÀÔ´Ï´Ù. GAS¿Í AT&T ¹®¹ý¿¡¼­´Â ¾î¼Àºí¸® ÄÚµåÀÇ Çü½Ä°ú ÀÌ°ÍÀÌ ÀÎÅÚ¿¡¼­ »ç¿ëÇÏ´Â ¹®¹ý°ú ¾î¶² Â÷ÀÌ°¡ ÀÖ´ÂÁö¸¦ ³ªÅ¸³À´Ï´Ù. ÀÌ ºÎºÐÀº ÀÎÅÚ¿¡¼­ »ç¿ëÇÏ´Â ¾î¼Àºí¸®(Macro Assembler³ª Turbo Assembler)¸¦ ¾Ë°í ÀÖ´Ù¸é ¸¹Àº µµ¿òÀÌ µÉ °ÍÀÔ´Ï´Ù. Inline Assembly´Â C Äڵ峻¿¡¼­ ¾î¼Àºí¸® Äڵ带 »ç¿ëÇÏ´Â ¹æ¹ý¿¡ ´ëÇÑ ±ÛÀÔ´Ï´Ù. Ä¿³Î Äڵ忡¼­ CPU¿¡ ÀÇÁ¸ÀûÀÎ ºÎºÐµéÀÇ »ó´ç¼ö´Â inline ¾î¼Àºí¸® ÄÚµå·Î ÀÛ¼ºµÇ¾î Àִµ¥, ÀÌ Çü½Ä¿¡ ³¸¼± »ç¶÷µéÀÌ À̸¦ ÀÌÇØÇϴµ¥ µµ¿òÀÌ µÇ¸®¶ó »ý°¢ÇÕ´Ï´Ù. ÀÌ ±ÛÀº x86 ¾î¼Àºí¸® Äڵ忡 ´ëÇØ ±âº»ÀûÀÎ Áö½ÄÀÌ ÀÖ´Ù°í °¡Á¤ÇÏ°í ÀÖ½À´Ï´Ù.

ÀÌ ¹®¼­´Â Linux Assembly HOWTO ¹®¼­¿Í Brennen's Guide to Inline Assembly, DJGPP QuickASM Programming Guide, GCC Manual, GAS Manual¿¡ ÀÖ´Â ³»¿ëÀ» ¿ä¾à Á¤¸®ÇÑ °ÍÀÔ´Ï´Ù. ±×´ë·Î »ç¿ëÇÑ ÄÚµåµéµµ ¸¹¾Æ¼­ ¾î¶² ¸é¿¡¼­´Â Á¤¸®Çߴٱ⠺¸´Ù´Â ±×³É ¿Å°å´Ù°í Çصµ ¹«¹æÇÒ µí ÇÕ´Ï´Ù (^^;). ¿©±â¼­ ´Ù·ç´Â ³»¿ë¿Ü¿¡ ´õ ÀÚ¼¼ÇÑ °ÍÀ» ¹Ù¶õ´Ù¸é ¸¶Áö¸· Àå Reference¿¡ ³ª¿À´Â ¹®¼­µéÀ» º¸½Ã±â ¹Ù¶ø´Ï´Ù. ƯÈ÷ x86 Assembly Language FAQ ¹®¼­´Â ¾î¼Àºí¸®¿¡ ´ëÇؼ­ ³¸¼± ºÐ¿¡°Ôµµ Å« µµ¿òÀÌ µÉ °ÍÀÔ´Ï´Ù. ½ÇÁ¦ CPU ¸í·É¾î¿¡ ´ëÇؼ­´Â °¢ CPU Á¦Á¶È¸»ç¿¡¼­ Á¦°øÇÏ´Â ¸Å´º¾óÀ» ÂüÁ¶ÇϽñ⠹ٶø´Ï´Ù. ±×·³ ¸®´ª½º¸¦ °øºÎÇϽô ºÐ²² µµ¿òÀÌ µÇ±æ ¹Ù¶ø´Ï´Ù.


1. GAS¿Í AT&T ¹®¹ý

GAS´Â GNU Assembler·Î¼­ GCC¿Í ÇÔ²² ½ÖÀ¸·Î »ç¿ëµÇ´Â AssemblerÀÌ´Ù. ÀÌ´Â 32-bit UNIX Compiler¸¦ À§ÇØ ¸¸µé¾îÁ³À¸¹Ç·Î, UNIX¿¡¼­ ÀϹÝÀûÀ¸·Î »ç¿ëµÇ´Â AT&T ¹®¹ýÀ» µû¸¥´Ù. ÀÌ ¹®¹ýÀº Intel¿¡¼­ »ç¿ëÇÏ´Â ¹®¹ý°ú´Â ¸¹ÀÌ ´Ù¸£´Ù. À̸¦ ºñ±³Çغ¸¸é :


2. Inline Assembly

inline assembly´Â high-level ¾ð¾î·Î µÈ ÄÚµå Áß°£¿¡ ³Ö¾î¼­ »ç¿ëÇÏ´Â ¾î¼Àºí¸® ÄÚµå·Î, ³×°¡Áö Ç׸ñÀ¸·Î ±¸¼ºµÇ¸ç, ´ÙÀ½°ú °°Àº Çü½ÄÀ¸·Î »ç¿ëÇÑ´Ù.

__asm__(¾î¼Àºí¸® ¹®Àå : Ãâ·Â : ÀÔ·Â : º¯°æµÈ ·¹Áö½ºÅÍ);

°¢ Ç׸ñÀº ÄÝ·Ð(':')À¸·Î ±¸ºÐµÇ¸ç, ¾î¼Àºí¸® ¹®ÀåÀº ¹Ýµå½Ã µé¾î°¡¾ß ÇÏÁö¸¸, µÚÀÇ ¼¼ Ç׸ñÀº ÇÊ¿ä¿¡ µû¶ó¼­ ³Ö°Å³ª »ý·«ÇÒ ¼ö ÀÖ´Ù. °¢ Ç׸ñÀº ´ÙÀ½°ú °°Àº Àǹ̸¦ °¡Áø´Ù.

¿¹Á¦ Äڵ带 º¸¸é :

	__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 Á¤¼ö

%0Àº ÀԷ¿¡¼­ ÁöÁ¤ÇÑ º¯¼ö¸¦ °¡¸®Å²´Ù. Áï ¿©±â¼­´Â i¶ó´Â º¯¼ö¸¦ °¡¸®Å°°Ô µÈ´Ù. ÀԷ¿¡¼­ ¿©·¯°³¸¦ ±â¼úÇϸé, ±â¼úÇÑ ¼ø¼­´ë·Î Â÷·Ê·Î %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"À̶ó°í ¼ýÀÚ·Î ½è´Âµ¥, ÀÌ´Â ¾Õ¿¡¼­ Áö½ÃÇÑ °ÍÀ» ´Ù½Ã °¡¸®Å°´Â °æ¿ìÀÌ´Ù. ¼ø¼­¿¡ µû¶ó Ãâ·Â "=r"Àº %0, ÀÔ·Â "0"Àº %1ÀÌ µÇ´Âµ¥, ÀÌ µÑÀ» °°Àº °ÍÀ» °¡¸®Å°°Ô ÇÏ°í ½ÍÀº °æ¿ì "0"À̶ó°í ÇÏ¿© %0°ú °°Àº °ÍÀ̶ó°í Áö½ÃÇØÁÖ´Â °ÍÀÌ´Ù. Áï ¿©±â¼­ %1Àº %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·Î ÁöÁ¤ÇÑ ±æÀ̸¸Å­ º¹»çÇÏ´Â °ÍÀÌ´Ù. ÀÌ Äڵ带 ½ÇÇàÇϸé edx, esi, edi ·¹Áö½ºÅÍ°¡ º¯°æµÇ°Ô µÇ¹Ç·Î, ¸¶Áö¸·¿¡ º¯°æµÈ ·¹Áö½ºÅÍ ¸ñ·Ï¿¡ ÀÌ ¼¼°³¸¦ ÁöÁ¤ÇØÁÖ¾ú´Ù.


3. Reference