| ÀÓº£µðµå ½Ã½ºÅÛ ¿£Áö´Ï¾î¸¦ À§ÇÑ ¸®´ª½º Ä¿³Î ºÐ¼® | ||
|---|---|---|
| ÀÌÀü | ºÎ·Ï C. Inline Assembly | |
¸®´ª½º Ä¿³Î¿¡ ÀÌ¹Ì »ç¿ëµÈ ¼ö ¸¹Àº ¿¹¸¦ ÅëÇØ ¾î¶² ½ÄÀ¸·Î ÀζóÀÎ ¾î¼Àºí¸®°¡ »ç¿ëµÆ´ÂÁö ¾Ë¾Æº¸ÀÚ.
¾Æ·¡ ¼Ò½º ÄÚµå´Â include/asm-i386/string.h¿¡ ÀÖ´Â strcpy() ÇÔ¼ö¸¦ °¡Á®¿Í ÄÄÆÄÀÏ ÇØº¸±â À§ÇØ Á¶±Ý Ãß°¡ÇÑ ÄÚµå´Ù.
/* test.c */
static inline char * strcpy(char * dest,const char *src)
{
int d0, d1, d2;
__asm__ __volatile__(
"1:\tlodsb\n\t"
"stosb\n\t"
"testb %%al,%%al\n\t"
"jne 1b"
: "=&S" (d0), "=&D" (d1), "=&a" (d2)
:"0" (src),"1" (dest) : "memory");
return dest;
}
int main()
{
char a[] = "1234";
char b[] = "4567";
strcpy(a, b);
return 0;
}
|
ÄÄÆÄÀÏÀº 'gcc -S -c test.c'¶ó°í ÇÑ´Ù. ±×·¯¸é test.s°¡ »ý±æ °ÍÀÌ´Ù. test.s´Â ´ÙÀ½°ú °°´Ù.
.file "test.c" .version "01.01" gcc2_compiled.: .section .rodata .LC0: .string "1234" .LC1: .string "5678" .text .align 4 .globl main .type main,@function main: pushl %ebp movl %esp,%ebp subl $24,%esp leal -8(%ebp),%eax movl .LC0,%edx movl %edx,-8(%ebp) movb .LC0+4,%al movb %al,-4(%ebp) leal -16(%ebp),%eax movl .LC1,%edx movl %edx,-16(%ebp) movb .LC1+4,%al movb %al,-12(%ebp) addl $-8,%esp leal -16(%ebp),%eax pushl %eax leal -8(%ebp),%eax pushl %eax call strcpy addl $16,%esp xorl %eax,%eax jmp .L3 .p2align 4,,7 .L3: movl %ebp,%esp popl %ebp ret .Lfe1: .size main,.Lfe1-main .align 4 .type strcpy,@function strcpy: pushl %ebp movl %esp,%ebp subl $28,%esp pushl %edi pushl %esi pushl %ebx movl 12(%ebp),%esi movl 8(%ebp),%edi #APP 1: lodsb stosb testb %al,%al jne 1b #NO_APP movl %esi,%ecx movl %edi,%edx movl %ecx,%ebx movl %ebx,-4(%ebp) movl %edx,%edx movl %edx,-8(%ebp) movl %eax,%eax movl %eax,-12(%ebp) movl 8(%ebp),%eax jmp .L2 .L2: leal -40(%ebp),%esp popl %ebx popl %esi popl %edi movl %ebp,%esp popl %ebp ret .Lfe2: .size strcpy,.Lfe2-strcpy .ident "GCC: (GNU) 2.95.3 20010315 (release)" |
ÀζóÀÎ ¾î¼Àºí¸®´Â #APP¿Í #NO_APP»çÀÌ¿¡ Á¸ÀçÇÑ´Ù.
outputÀÇ ±¸¼ºÀ» ³ªÅ¸³½´Ù. "=&S" (d0)´Â d0¸¦ 'si' ·¹Áö½ºÅÍ¿¡ ÀúÀåÇÏ´Â °ÍÀ̰í "=&D" (d1)Àº d1À» 'di' ·¹Áö½ºÅÍ¿¡ ÀúÀåÇ϶õ °ÍÀ̰í "=&a" (d2)´Â d2¸¦ 'a' ·¹Áö½ºÅÍ¿¡ ÀúÀåÇ϶õ °ÍÀÌ´Ù.
test.s¿¡ ÀÇÇÏ¸é ¾î¼Àºí¸® Äڵ尡 ½ÇÇàµÈ ÈÄ outputÀ¸·Î d0, d1, d2°¡ Àִµ¥ #NO_APP ¹Ù·Î ¹ØÀÇ 3ÁÙÀÌ ÀÌ ¿ªÇÒÀ» ÇÑ´Ù. d2´Â %ebx¿¡ ÇÒ´çµÆÀ½À» ¾Ë ¼ö ÀÖ´Ù.
inputÀÇ ±¸¼ºÀ» ³ªÅ¸³½´Ù. "0" (src)´Â src°¡ 0¹øÂ° ¿ÀÆÛ·£µå¿Í °°Àº À§Ä¡¸¦ Á¡À¯Ç϶õ ¸»·Î %0ÀÎ d0¸¦ ÀǹÌÇÑ´Ù. ¶Ç d0°¡ si¸¦ »ç¿ëÇϹǷΠ°á±¹ siÀÇ Ãʱ⠰ªÀÌ src°¡µÈ´Ù. dest´Â %1ÀÎ di¿¡ ÀԷµȴÙ.
test.s¿¡ ÀÇÇϸé #APP ¹Ù·Î ÀüÀÇ µÎÁÙÀÌ input¿¡ ÇØ´çÇϰí %esi¿Í %edi¿¡ src, dest¸¦ ÀÔ·ÂÇØ ÁØ´Ù.
clobber¿¡ ÁöÁ¤µÈ "memory"´Â ÄÄÆÄÀÏ·¯¿¡°Ô ¾î¼Àºí¸®Äڵ尡 ¸Þ¸ð¸®ÀÇ ¾îµò°¡¸¦ º¯°æÇÑ´Ù°í °¡¸£ÃÄ ÁÖ´Â °ÍÀÌ´Ù. ÀÌ °ÍÀ» »ç¿ëÇÏÁö ¾ÊÀ¸¸é ¾î¼Àºí¸®Äڵ忡¼ ¸Þ¸ð¸®ÀÇ ³»¿ëÀ» º¯°æÇÏ´Â °ÍÀ» ÄÄÆÄÀÏ·¯´Â ÀüÇô ¾Ë ¼ö ¾ø´Ù. Àß ¸øÇÏ¸é ¾î¼Àºí¸®¿¡¼ °íÄ£ °ª°ú ´Ù¸¥ °ªÀ» ÄÄÆÄÀÏ·¯ ´Â »ç¿ëÇϰí ÀÖÀ» °¡´É¼ºµµ ÀÖ´Ù. "memory"¸¦ ¸í½ÃÇØ ÁÖ¸é ÄÄÆÄÀÏ·¯´Â ¾î¼Àºí¸® Äڵ带 ½Ç ÇàÇϱâ Àü/ÈÄ¿¡ ·¹Áö½ºÅÍ¿¡ ÀúÀåµÇ¾î ÀÖ´Â ¸ðµç º¯¼öÀÇ °ªÀ» °»½ÅÇϵµ·Ï ÇÑ´Ù.
1:Àº labelÀ» ÀǹÌÇÑ´Ù. loadsb ¸í·ÉÀ¸·Î al ·¹Áö½ºÅÍ¿¡ es:esiÀÇ ³»¿ëÀ» ÀÐ¾î ¿Â´Ù. ¿©±â¼ srcÀÇ ³»¿ëÀ» ÀÐ¾î ¿Â´Ù. ¸í·É ½ÇÇàÈÄ esi´Â ÀÚµ¿À¸·Î 1ÀÌ Áõ°¡ÇÑ´Ù(¹ÙÀÌÆ® ´ÜÀ§·Î Àб⠶§¹®).
alÀÇ °ªÀ» es:edi¿¡ ÀúÀåÇÑ´Ù. ediµµ ¸í·É ½ÇÇà ÈÄ 1 Áõ°¡ÇÑ´Ù.
alÀÇ ³»¿ëÀÌ 0ÀÎÁö Å×½ºÆ®ÇÑ´Ù. ½ºÆ®¸µÀ» º¹»çÇÒ ¶© NULL ij¸¯ÅͰ¡ ³ª¿Ã ¶§ ±îÁö º¹»çÇϱ⠶§¹®¿¡ 0ÀÎÁö ÆÇº°ÇÑ´Ù.
0ÀÌ ¾Æ´Ñ °æ¿ì, Áï NULL ij¸¯ÅͰ¡ ¾Æ´Ñ °æ¿ì °è¼ÓÇØ¼ º¹»çÇÑ´Ù.
arch/i386/kernel/trap.c¿¡ ÀÖ´Â _set_gate()ÀÇ ³»¿ëÀ» °¡Á®´Ù ÄÄÆÄÀÏ Çϱâ À§ÇØ ¾à°£ º¯°æÇÑ °ÍÀÌ´Ù.
/* sg.c */
#define __KERNEL_CS 0x10
#define _set_gate(gate_addr,type,dpl,addr) \
do { \
int __d0, __d1; \
__asm__ __volatile__ ("movw %%dx,%%ax\n\t" \
"movw %4,%%dx\n\t" \
"movl %%eax,%0\n\t" \
"movl %%edx,%1" \
:"=m" (*((long *) (gate_addr))), \
"=m" (*(1+(long *) (gate_addr))), "=&a" (__d0), "=&d" (__d1) \
:"i" ((short) (0x8000+(dpl<<13)+(type<<8))), \
"3" ((char *) (addr)),"2" (__KERNEL_CS << 16)); \
} while (0)
int main()
{
_set_gate(0, 1, 2, 3);
return 0;
} |
'gcc -S -c sg.c'·Î ÄÄÆÄÀÏÇÑ °ÍÀº ´ÙÀ½°ú °°´Ù.
.file "sg.c" .version "01.01" gcc2_compiled.: .text .align 4 .globl main .type main,@function main: pushl %ebp movl %esp,%ebp subl $24,%esp nop .p2align 4,,7 .L3: movl $3,%edx movl $1048576,%ecx movl %ecx,%eax #APP movw %dx,%ax movw $-16128,%dx movl %eax,0 movl %edx,4 #NO_APP movl %eax,%ecx movl %ecx,-4(%ebp) movl %edx,%eax movl %eax,-8(%ebp) .L5: jmp .L4 .p2align 4,,7 .L6: jmp .L3 .p2align 4,,7 .L4: xorl %eax,%eax jmp .L2 .p2align 4,,7 .L2: movl %ebp,%esp popl %ebp ret .Lfe1: .size main,.Lfe1-main .ident "GCC: (GNU) 2.95.3 20010315 (release)" |
inputÀ¸·Î Á¤ÀÇµÈ °Í µéÀÌ´Ù. "3", "2"´Â °¢°¢ %3(__d0), %2(__d1)·Î ´ëÀÀµÇµµ·Ï ÇÑ´Ù. $APP ÀüÀÇ 3ÁÙ Áß À 2ÁÙÀÌ "3", "2"¿¡ ÇØ´çÇÏ´Â °ÍµéÀÌ´Ù.
outputÀ¸·Î Á¤ÀÇµÈ °Í µé. %0Àº °ªÀÌ 0À̵ǰí(main¿¡¼ _set_gate(0, 1, 2, 3)À¸·Î Ç߱⠶§¹®¿¡) %1Àº 4°¡ µÈ´Ù.