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ÀÇ °ªÀ» º¯°æÇÏ´Â °æ¿ì¿£ ¿ø·¡ÀÇ °ªÀ¸·Î º¹¿øÇؾßÇÕ´Ï´Ù.