配列プログラミング
Brainfuckで+を65回実行してから.する時のアセンブリを配列上に書いてみる。
ちなみにアセンブリが無駄だらけなのは手書きで失敗したからCで書いて最適化無しで機械語に落としたものをそのまま展開しているからなので、ご容赦願いたい。
これをベースに最適化すれば良いと思う。
あと、インデントもおかしい気がするがなおすのめんどいから放っといてくれ。
#include <stdio.h> #include <fcntl.h> #include <sys/types.h> #include <unistd.h> #include <sys/mman.h> #include <assert.h> int stack[32768], *sp = stack; void *func_table[2] = {(void *)putchar, (void *)getchar}; unsigned char *program; void **funcp = func_table; int main(void) { long psize; int i = 0, j; #ifdef BSD psize = getpagesize(); #else psize = sysconf(_SC_PAGE_SIZE); #endif if((posix_memalign((void **)&program, psize, psize))) err(1, "posix_memalign"); if(mprotect((void*)program, psize, PROT_READ | PROT_WRITE | PROT_EXEC)) err(1, "mprotect"); program[i++] = 0x55;// push %ebp program[i++] = 0x89; program[i++] = 0xe5;// mov %esp,%ebp program[i++] = 0x83; program[i++] = 0xec; program[i++] = 0x18;// sub $0x18,%esp program[i++] = 0x8b; program[i++] = 0x5d; program[i++] = 0x08;// mov 0x8(%ebp),%ebx program[i++] = 0x8b; program[i++] = 0x75; program[i++] = 0x0c;// mov 0xc(%ebp),%esi for(j = 0; j < 65; j++) { program[i++] = 0x8b; program[i++] = 0x55; program[i++] = 0x08;// mov 0x8(%ebp),%edx program[i++] = 0x8b; program[i++] = 0x02;// mov (%edx),%eax program[i++] = 0x40;// inc %eax program[i++] = 0x89; program[i++] = 0x02;// mov %eax,(%edx) } program[i++] = 0x8b; program[i++] = 0x45; program[i++] = 0x0c;// mov 0xc(%ebp),%eax program[i++] = 0x8b; program[i++] = 0x00;// mov (%eax),%eax program[i++] = 0x89; program[i++] = 0xc2;// mov %eax,%edx program[i++] = 0x8b; program[i++] = 0x45; program[i++] = 0x08;// mov 0x8(%ebp),%eax program[i++] = 0x8b; program[i++] = 0x00;// mov (%eax),%eax program[i++] = 0x89; program[i++] = 0x04; program[i++] = 0x24;// mov %eax,(%esp) program[i++] = 0xff; program[i++] = 0xd2;// call *%edx program[i++] = 0xc9;// leave program[i++] = 0xc3;// ret ((void (*)(int *, void**))program)(sp, funcp); // free(program); return 0; }