2.2. Assembly

ÀÌ ¼½¼Ç¿¡¼­´Â gcc inline assembly¿¡¼­ ½ÇÁ¦ assembly¸¦ Àû´Â ºÎºÐ (¾ÕÀ¸·Î´Â ÀÌ ºÎºÐÀ» asms¶ó°í ºÎ¸£°Ú½À´Ï´Ù)¿¡ ´ëÇØ ¼³¸íÇÕ´Ï´Ù.

asmsÀÇ ³»¿ëÀº ±×´ë·Î ÄÄÆÄÀÏ µÈ assembly¿Í ÇÔ²² gasmÀ¸·Î ³Ñ¾î°¡¹Ç·Î gasmÀÇ ¹®¹ýÀ» µû¶ó¾ß ÇÕ´Ï´Ù. GasmÀº target ÀÎÀÚ°¡ µÚ¿¡¿À´Â AT&T ¹®¹ýÀ» µû¸£¸ç instruction »çÀÌÀÇ ±¸ºÐÀº ¼¼¹ÌÄÝ·ÐÀ̳ª °³Ç๮ÀÚ·Î ÇÏ°í ·¹Áö½ºÅ͵éÀº %registerÀÇ ÇüÅ·ΠǥÇöÇÕ´Ï´Ù. ix86 °è¿­ÀÇ ´ëºÎºÐÀÇ ¾î¼Àºí·¯¿Í intel manualÀº target ÀÎÀÚ°¡ ¾Õ¿¡¿À´Â intel ¹®¹ýÀ» µû¸£°í ÀÖÀ¸¹Ç·Î manualÀ» º¸°Å³ª ´Ù¸¥ ¾î¼Àºí·¯ÀÇ Äڵ带 º¼ ¶§ ÁÖÀÇÇϽñ⠹ٶø´Ï´Ù. ´õ ÀÚ¼¼ÇÑ ³»¿ëÀº gasm ¸Þ´º¾ó°ú intel processor manualÀ» ÂüÁ¶Çϼ¼¿ä.

2.2.1. µé¿©¾²±â & Ä¿¸àÆ® ´Þ±â

Gcc°¡ »ý¼ºÇÏ´Â assembly ÄÚµå´Â ½Éº¼ Á¤ÀǵîÀ» Á¦¿ÜÇϰí´Â ¸ðµÎ ÅÇ Çϳª¸¸Å­ µé¿©¾²±â°¡ µÇ¾îÀÖ½À´Ï´Ù. Inline assembly´Â #APP¿Í #NO APP»çÀÌ¿¡ µé¾î°¡´Âµ¥ ÅÇ Çϳª¸¸Å­ µé¿©¾²±â°¡ µÈ »óÅ¿¡¼­ ¹®ÀÚ¿­ÀÌ ±×´ë·Î µé¾î°©´Ï´Ù. µû¶ó¼­ Assembly outputÀ» Àб⠽±°Ô Çϱâ À§ÇØl¼± °¢ instructionµé »çÀ̸¦ \n\t·Î ±¸ºÐÇØÁÖ¸é µË´Ï´Ù.


__asm__ __volatile__("line1\n\tline2\line3");
	

À» ÄÄÆÄÀÏÇϸé


#APP
	line1
	line2
	line3
#NO_APP
	

°¡ µË´Ï´Ù. ±×·±µ¥ ³»¿ëÀÌ ¸¹¾ÆÁö¸é À§Ã³·³ ÇÑ ÁÙ·Î Àû±â°¡ Èûµé¾îÁý´Ï´Ù. ±×·± °æ¿ì¿£ ¾Æ·¡Ã³·³ ÇÏ¸é µË´Ï´Ù.


__asm__ __volatile__(
	"pushl  %%ebp		# comment	\n\t"
	"movl   %%esp, %%eax			\n\t"
	"cli"					\n\t"
	"incl   %0				\n\t"
	"movl   %8, %%esp			\n\t"
	"sti"					\n\t"
	"pushl  %%eax				\n\t"
	"call   *%7				\n\t"
	"cli					\n\t"
	"decl   %0				\n\t"
	"popl   %%esp		# comment 2	\n\t"
	"sti					\n\t"
	"popl   %%ebp				"
	: "=m" (processor0->intr_lv),
	  "=&a" (a), "=b" (b), "=c" (c), "=d" (d), "=D" (D), "=S" (S)
	: "m" (jmpaddr), "g" (processor0->bh_stack_top));
	

ÄÄÆÄÀÏ Çϸé,

	  
#APP
	pushl   %ebp		# comment
	movl    %esp, %eax
	cli
	incl    processor0+20
	movl    processor0+76, %esp
	sti
	pushl   %eax
	call    *-40(%ebp)
	cli
	decl    processor0+20
	popl    %esp		# comment 2
	sti
	popl    %ebp
#NO_APP
	

Gasm¿¡¼­ Ä¿¸àÆ®´Â #ºÎÅÍ ±× ÁÙÀÇ ³¡±îÁöÀ̸ç inline assembly¿¡¼­µµ °°Àº ¹æ¹ýÀ¸·Î ¾µ ¼ö ÀÖ½À´Ï´Ù.

2.2.2. Register Á÷Á¢ ÁöÁ¤Çϱâ

À§ÀÇ ¿¹¿¡¼­ %%eax, %%esp°°Àº °ÍµéÀ» º¼ ¼ö Àִµ¥ %%´Â ½ÇÁ¦ output¿¡¼­ % Çϳª¸¦ Ãâ·ÂÇÕ´Ï´Ù. ƯÁ¤ ·¹Áö½ºÅ͸¦ ½á¾ßÇÒ ¶§´Â %nÀ¸·Î Á¤ÇØÁ൵ µÇÁö¸¸ input, output ÁöÁ¤¿¡¼­ ¾²°í ½ÍÀº ·¹Áö½ºÅ͸¦ ÁöÁ¤ÇÏ°í ¾îÂ÷ÇÇ ±× ·¹Áö½ºÅͰ¡ ÇÒ´çµÉ °ÍÀ» ¾Ë°í ÀÖÀ¸¹Ç·Î %%register¸¦ ¾²´Â °ÍÀÌ ´õ ÀÐ°í ¾²±â ÆíÇÕ´Ï´Ù.

ÇÑ °¡Áö ÁÖÀÇÇÒ Á¡Àº ¸¸¾à input, outputÀÌ Çϳªµµ ¾ø´Â °æ¿ì¿¡´Â asms¿¡ ´ëÇÑ ÀÎÀÚġȯÀÌ ÀüÇô ÀϾÁö ¾Ê°í %%µµ %·Î ¹Ù²îÁö ¾Ê½À´Ï´Ù. Áï, input, outputÀÌ ¸ðµÎ ¾øÀ» ¶§´Â %%register´ë½Å %register¶ó°í ÇØ¾ßÇÕ´Ï´Ù.

2.2.3. Inline assembly¾È¿¡¼­ ÇÔ¼ö Á¤ÀÇÇϱâ

ÇÔ¼ö¸¦ assembly·Î Á¤ÀÇÇØ¾ßÇÏ´Â °æ¿ì´Â ÁÖ·Î ÇÔ¼öÀÇ entry³ª exitÀÌ CÀÇ convention°ú ´Þ¶ó¼­ CÇÔ¼ö ¾È¿¡¼­ inline assembly·Î ¸¸µé ¼ö ¾ø´Â °æ¿ìÀÔ´Ï´Ù. ¹°·Ð µû·Î ¾î¼Àºí¸® È­ÀÏÀ» ¸¸µé¾îµµ µÇÁö¸¸ ÀÌ·± ÇÔ¼ö°¡ ¸î °³ µÇÁö ¾ÊÀ» ¶§´Â ¹ø°Å·Ó±â ¶§¹®¿¡ inline assembly·Î ¸¸µå´Â °ÍÀÌ ´õ ÆíÇÕ´Ï´Ù.

¶Ç, assembly·Î ¸¸µç ÇÔ¼ö¿¡¼­ C ÇÁ·Î±×·¥¿¡¼­ ¾²´ø Àü¿ªº¯¼ö, ¸ÅÅ©·ÎµîÀ» ¾²°ÔµÇ´Â °æ¿ì°¡ Àִµ¥, ÀϹÝÀûÀÎ °æ¿ì assembly ¼Ò½º¸¦ C preprocessor·Î ó¸®ÇÏ°í ¸µÅ©ÇÏ¸é µÇÁö¸¸ Àü¿ªÀ¸·Î ¼±¾ðµÈ structure¸¦ »ç¿ëÇÏ·Á¸é ¹®Á¦°¡ µË´Ï´Ù. ½ºÅ©¸³µåµîÀ» »ç¿ëÇØ¼­ memberµéÀÇ offsetÀ» Æ÷ÇÔÇÑ Çì´õÈ­ÀÏÀ» ¸¸µç ÈÄ C preprocessor¸¦ »ç¿ëÇÏ¸é °¡´ÉÇϱä ÇÏÁö¸¸ (½ÇÁ¦·Î freebsd Ä¿³Î¿¡¼± ÀÌ ¹æ¹ýÀ» »ç¿ëÇÕ´Ï´Ù) »ó´çÈ÷ ±ÍÂúÀº ÀÏÀÌ µÇ¹ö¸³´Ï´Ù. ÀÌ·± °æ¿ì¿¡µµ inline assembly·Î ÇÔ¼ö¸¦ Á¤ÀÇÇØ ÁÖ´Â °ÍÀÌ ÈξÀ °£ÆíÇÕ´Ï´Ù.

AsmsÀÇ ³»¿ëÀÌ output¿¡ ±×´ë·Î Ãâ·ÂµÇ±â ¶§¹®¿¡ ½Éº¼À» Á¤ÀÇÇÏ´Â directiveµµ »ç¿ëÇÒ ¼ö ÀÖ½À´Ï´Ù. ¿ì¼± ¿¹¸¦ º¸°Ú½À´Ï´Ù.

	  
struct {
	int a;
	int b;
} mine = { 0, 0 };

int iasm_test_func(int arg);
static int iasm_test_func2(void);

static void
__iasm_function_dummy(void)
{
	__asm__ __volatile__(
		".globl iasm_test_func		\n\t"
		"iasm_test_func:		\n\t"
		"pushl	4(%%esp)		\n\t"
		"pushl	%2			\n\t"
		"pushl	%1			\n\t"
		"pushl	%0			\n\t"
		"call	printf			\n\t"
		"addl	$16, %%esp		\n\t"
		"ret				"
		:
		: "i" ("hello world.. mine.a=%d mine.b=%d arg=%d\n"),
		  "g" (mine.a), "g" (mine.b));

	__asm__ __volatile__(
		"iasm_test_func2:		\n\t"
		"pushl	$32			\n\t"
		"call	iasm_test_func		\n\t"
		"addl	$4, %esp		");
}

int
main(void)
{
	mine.a = 123;
	mine.b = 321;
	iasm_test_func(16);
	return iasm_test_func2();
}
	

¿ì¼± Á¤ÀÇÇÒ µÎ ÇÔ¼öÀÇ prototypeÀ» º¼ ¼ö ÀÖ½À´Ï´Ù. iasm_test_func2´Â staticÀÎ °É ÁÖÀÇÇØ¼­ º¸½Ã±â ¹Ù¶ø´Ï´Ù.

Inline assembly´Â ÇÔ¼ö¹Û¿¡¼­´Â ¾²ÀÏ ¼ö ¾øÀ¸¹Ç·Î __iasm_function_dummy¶ó´Â ÇÔ¼ö¸¦ ¸¸µé°í ±× ¾ÈÀÇ µÎ inline assembly¿¡¼­ °¢°¢ ÇÔ¼ö¸¦ Á¤ÀÇÇß½À´Ï´Ù. ù¹øÂ° ÇÔ¼ö´Â iasm_test_func·Î ½Éº¼ Á¤ÀÇ ¹Ù·ÎÀ§ÀÇ .globl directive·Î ¸µÅ©½Ã ¿ÜºÎ¿¡ º¸ÀÌ´Â ½Éº¼ÀÓÀ» ¾Ë·ÁÁÖ¾ú°í µÎ¹øÂ°ÀÇ iasm_test_func2ÇÔ¼ö´Â .globlÀÌ ¾øÀ¸¹Ç·Î ¸µÅ©½Ã ¿ÜºÎ¿¡¼­ º¸ÀÌÁö ¾Ê´Â static ÇÔ¼ö°¡ µË´Ï´Ù.

Gcc´Â ÄÄÆÄÀÏ ÇÒ ¶§ iasm_test_func2°¡ inline assembly¾È¿¡ Á¤ÀǵǾî ÀÖ´Â °É ¾ËÁö ¸øÇϹǷΠstaticÇÔ¼ö°¡ Á¤ÀǵÇÁö ¾Ê¾Ò´Ù°í °æ°í¸¦ ÇÏÁö¸¸ ¹«½ÃÇÏ¸é µË´Ï´Ù.

iasm_test_func´Â Á¤¼ö ÀÎÀÚ¸¦ Çϳª ¹Þ°í, Àü¿ª ±¸Á¶Ã¼ÀÎ mineÀÇ ³»¿ë°ú ¹ÞÀº ÀÎÀÚÀÇ °ªÀ» printf¸¦ »ç¿ëÇØ Ãâ·ÂÇÏ´Â ÇÔ¼ö ÀÔ´Ï´Ù. Inline assembly¸¦ º¸¸é inputÀ¸·Î format ¹®ÀÚ¿­, mine.a, mine.b°¡ »ç¿ëµÇ´Âµ¥ "i"´Â immediate integer operand·Î format ¹®ÀÚ¿­ÀÇ ½ÃÀÛ ÁÖ¼Ò°¡ ±×´ë·Î operand°¡ µË´Ï´Ù. "g"´Â immediate, ¹ü¿ë ·¹Áö½ºÅÍ ¶Ç´Â memory operand¸¦ ¶æÇÏ´Â °ÍÀ¸·Î compiler°¡ ÀûÀýÈ÷ ¼±ÅÃÇÕ´Ï´Ù.

iasm_test_func2´Â iasm_test_func(32)¸¦ È£ÃâÇÏ´Â ÇÔ¼öÀÔ´Ï´Ù.

À§ÀÇ ÇÁ·Î±×·¥À» ÄÄÆÄÀÏÇÏ¸é ¾Æ·¡¿Í °°Àº assembly°¡ µË´Ï´Ù. (gcc -fomit-frame-pointer -mpreferred-stack-boundary=2 -O2 -S iasm_function.c)

	  
	.file	"iasm_function.c"
	.version	"01.01"
gcc2_compiled.:
.globl mine
.data
	.align 4
	.type	 mine,@object
	.size	 mine,8
mine:
	.long 0
	.long 0
.section	.rodata
	.align 32
.LC0:
	.string	"hello world.. mine.a=%d mine.b=%d arg=%d\n"
.text
	.align 4
	.type	 __iasm_function_dummy,@function
__iasm_function_dummy:
#APP
	.globl iasm_test_func		
	iasm_test_func:		
	pushl	4(%esp)		
	pushl	mine+4			
	pushl	mine			
	pushl	$.LC0			
	call	printf			
	addl	$16, %esp		
	ret				
	iasm_test_func2:		
	pushl	$32			
	call	iasm_test_func		
	addl	$4, %esp		
#NO_APP
	ret
.Lfe1:
	.size	 __iasm_function_dummy,.Lfe1-__iasm_function_dummy
	.align 4
.globl main
	.type	 main,@function
main:
	movl $123,mine
	movl $321,mine+4
	pushl $16
	call iasm_test_func
	call iasm_test_func2
	addl $4,%esp
	ret
.Lfe2:
	.size	 main,.Lfe2-main
	.ident	"GCC: (GNU) 2.95.4 20010902 (Debian prerelease)"
	

__iasm_function_dummy¾È¿¡ µÎ °³ÀÇ inline assembly°¡ #APP, #NOAPP ¾È¿¡¼­ iasm_test_func, iasm_test_func2¸¦ Á¤ÀÇÇϰí ÀÖ°í, iasm_test_funcÀÇ %1, %2´Â direct addressingÀ¸·Î ó¸®µÈ °ÍÀ» º¼ ¼ö ÀÖ½À´Ï´Ù.