InputÀ̳ª outputÀ¸·Î »ç¿ëµÇÁö ¾ÊÁö¸¸ ¾î¶² ·¹Áö½ºÅ͸¦ inline assembly¿¡¼ Àӽ÷Π»ç¿ëÇÒ ¶§ clobber list¿¡ ±× ·¹Áö½ºÅ͸¦ Àû½À´Ï´Ù. Clobber list¿¡ ÀÖ´Â ·¹Áö½ºÅÍ´Â input, output¿¡ ÀÖ´Â ·¹Áö½ºÅÍ¿Í °ãÄ¥ ¼ö ¾ø½À´Ï´Ù. Áï, clobber list¿¡ ÁöÁ¤µÈ ·¹Áö½ºÅÍ´Â input, outputÀ» À§ÇÑ ·¹Áö½ºÅÍ ÇÒ´ç¿¡¼ ºüÁö°Ô µË´Ï´Ù.
¸¸¾à ¾î¶² ·¹Áö½ºÅͰ¡ inputÀ¸·Î ¾²ÀÌ°í ±× °ªÀÌ ¹Ù²îÁö¸¸ outputÀ¸·Î ¾²ÀÌÁø ¾Ê´Â´Ù¸é clobber list¿¡ ±× ·¹Áö½ºÅ͸¦ Á¤ÇØÁÙ ¼ö ¾ø½À´Ï´Ù. ÀÌ·± °æ¿ì¿£ dummy º¯¼ö¸¦ Çϳª ¼±¾ðÇÑ ÈÄ output ÀÎÀڷεµ ÁöÁ¤ÇØÁÖ¾î¾ß ÇÕ´Ï´Ù.
#include <stdio.h> #include <stdlib.h> int main(int argc, char **argv) { int a, b, r; a = atoi(argv[1]); b = atoi(argv[2]); __asm__ __volatile__( "movl %1, %%eax \n\t" "addl %2, %%eax \n\t" "mull %%eax " : "=&a" (r) : "g" (a), "g" (b)); printf("a=%d, b=%d, r=%d\n", a, b, r); return 0; } |
µÎ Á¤¼ö¸¦ ÀÔ·Â¹Þ¾Æ ÇÕÀÇ Á¦°öÀ» ±¸ÇÏ´Â ÇÁ·Î±×·¥ÀÔ´Ï´Ù. À§ÀÇ ÇÁ·Î±×·¥À» ÄÄÆÄÀÏÇÏ¸é ´ÙÀ½°ú °°Àº °á°ú°¡ ³ª¿É´Ï´Ù.
.file "clobber_list.c" .version "01.01" gcc2_compiled.: .section .rodata .LC0: .string "a=%d, b=%d, r=%d\n" .text .align 4 .globl main .type main,@function main: pushl %esi pushl %ebx movl 16(%esp),%ebx pushl $0 pushl $10 pushl $0 pushl 4(%ebx) call __strtol_internal movl %eax,%esi addl $16,%esp pushl $0 pushl $10 pushl $0 pushl 8(%ebx) call __strtol_internal movl %eax,%edx addl $16,%esp #APP movl %esi, %eax addl %edx, %eax mull %eax #NO_APP pushl %eax pushl %edx pushl %esi pushl $.LC0 call printf xorl %eax,%eax addl $16,%esp popl %ebx popl %esi ret .Lfe1: .size main,.Lfe1-main .ident "GCC: (GNU) 2.95.4 20010902 (Debian prerelease)" |
b°¡ %edx·Î ÇÒ´çµÇ¾úÀ½À» ¾Ë ¼ö ÀÖ½À´Ï´Ù. b´Â inputÀ̹ǷΠ°ªÀÌ º¯ÇÏÁö ¾ÊÀº °ÍÀ¸·Î »ý°¢ÇØ inline assemblyÈÄ¿¡ printf¸¦ ºÎ¸¦ ¶§µµ %edxÀÇ °ªÀ» ±×´ë·Î »ç¿ëÇÏ´Â °ÍÀ» º¼ ¼ö ÀÖ½À´Ï´Ù. À§ÀÇ ÇÁ·Î±×·¥À» ½ÇÇàÇØº¸°Ú½À´Ï´Ù.
$ ./a.out 4 6 a=4, b=0, r=100 |
°á°ú°ªÀº ¸ÂÁö¸¸ bÀÇ °ªÀÌ 0À¸·Î Ãâ·ÂµË´Ï´Ù. ÀÌ´Â mull instructionÀÌ °á°ú°ªÀ» %edx¿Í %eax¿¡ °ÉÃÄ ÀúÀåÇϱ⠶§¹®ÀÔ´Ï´Ù. À§ÂÊ °á°ú°ªÀÎ %edx°¡ 0ÀÌ µÇÁö¸¸ ÄÄÆÄÀÏ·¯´Â ±× °ªÀÌ º¯ÇÏÁö ¾Ê¾Ò´Ù°í »ý°¢Çϱ⠶§¹®¿¡ bÀÇ °ªÀÌ ¾û¶×ÇÏ°Ô µÈ °Í ÀÔ´Ï´Ù. ÀÌó·³ input, output ¾î´À °ÍÀ¸·Îµµ ¾²ÀÌÁö ¾ÊÁö¸¸ ±× °ªÀÌ º¯ÇÏ´Â °æ¿ì¿¡´Â clobber list¿¡ ±× ·¹Áö½ºÅÍÀÇ À̸§À» Àû¾îÁÖ¸é µË´Ï´Ù.
#include <stdio.h> #include <stdlib.h> int main(int argc, char **argv) { int a, b, r; a = atoi(argv[1]); b = atoi(argv[2]); __asm__ __volatile__( "movl %1, %%eax \n\t" "addl %2, %%eax \n\t" "mull %%eax " : "=&a" (r) : "g" (a), "g" (b) : "edx" ); printf("a=%d, b=%d, r=%d\n", a, b, r); return 0; } |
ÄÄÆÄÀÏµÈ °á°ú´Â ´ÙÀ½°ú °°½À´Ï´Ù.
.file "clobber_list.c" .version "01.01" gcc2_compiled.: .section .rodata .LC0: .string "a=%d, b=%d, r=%d\n" .text .align 4 .globl main .type main,@function main: pushl %esi pushl %ebx movl 16(%esp),%ebx pushl $0 pushl $10 pushl $0 pushl 4(%ebx) call __strtol_internal movl %eax,%esi addl $16,%esp pushl $0 pushl $10 pushl $0 pushl 8(%ebx) call __strtol_internal movl %eax,%ecx addl $16,%esp #APP movl %esi, %eax addl %ecx, %eax mull %eax #NO_APP pushl %eax pushl %ecx pushl %esi pushl $.LC0 call printf xorl %eax,%eax addl $16,%esp popl %ebx popl %esi ret .Lfe1: .size main,.Lfe1-main .ident "GCC: (GNU) 2.95.4 20010902 (Debian prerelease)" |
bÀÇ °ªÀ» ecx·Î ÇÒ´çÇÑ °ÍÀ» º¼ ¼ö ÀÖ½À´Ï´Ù.
¹°·Ð °á°ú°ªµµ Á¦´ë·Î ³ª¿É´Ï´Ù.
$ ./a.out 6 4 a=6, b=4, r=100 |
À§ÀÇ ¿¹¿¡¼ º¼ ¼ö ÀÖµíÀÌ clobber list¿¡´Â ·¹Áö½ºÅÍÀÇ À̸§À» Á÷Á¢ Àû½À´Ï´Ù. ¾²ÀÌ´Â À̸§µéÀº ´ÙÀ½°ú °°½À´Ï´Ù.
i386 specific ah, al, ax, eax bh, bl, bx, ebx ch, cl, cx, ecx dh, dl, dx, edx si, esi di, edi |
(floating ·¹Áö½ºÅ͵éÀº ¾î¶»°Ô ÁöÁ¤ÇÏ´Â Áö ¸ð¸£°Ú½À´Ï´Ù. ¾Æ½Ã´Â ºÐ?)
Condition codeÀÇ °ªÀÌ ¹Ù²ñÀ» ³ªÅ¸³»´Â cc°¡ ÀÖÁö¸¸, ix86¿¡¼± ÇÊ¿äÇÏÁö ¾Ê½À´Ï´Ù. ¶Ç, stack, frame pointerÀÎ esp/sp, ebp/bpµµ ÁöÁ¤Àº ÇÒ ¼ö ÀÖÁö¸¸ ¾Æ¹«·± È¿·Âµµ ¾ø½À´Ï´Ù. esp, ebpÀÇ °ªÀ» º¯°æÇÏ´Â °æ¿ì¿£ ¿ø·¡ÀÇ °ªÀ¸·Î º¹¿øÇؾßÇÕ´Ï´Ù.