/* postforth-2 interpreter */ _start: ; .global _start ; nop ; /* so gdb breakpoint can always be _start+1 */ lea 4(%esp) , %ebp ; /* argv[0] */ movl $5 , %eax ; movl 4(%ebp) , %ebx ; int $0x80 ; /* open argv[1] */ /* assume we got an open file, and save it for later */ movl %eax , %ebx ; movl %eax , %edi ; /* for fstat and mmap */ movl $108 , %eax ; movl $scratchpad , %ecx ; int $0x80 ; /* fstat */ /* assume fstat went OK */ movl $90 , %eax ; /* mmap */ movl $0x0 , scratchpad+0x10 ; /* overwriting st_gid field... */ movl $scratchpad+0x10 , %ebx ; /* giving mmap a null pointer as "hint" */ /* st_size follows this in memory, which is also passed to kernel */ movl scratchpad+0x08 , %ecx ; /* st_prot, protection bits */ andl $7 , %ecx ; /* only low 3 bits count */ movl %ecx , scratchpad+0x18 ; /* overwrite st_blksize */ movl $1 , scratchpad+0x1c ; /* overwrite st_blocks with flag bits */ movl %edi , scratchpad+0x20 ; /* file descriptor, remember? */ movl $0 , scratchpad+0x24 ; /* map offset of zero from start */ int $0x80 ; movl $datastack, %esi ; /* initialize data stack pointer %esi */ movl scratchpad+0x14 , %ebx ; /* length of .text of loaded program */ movl %ebx , (%esi) ; /* make it available to that program */ call *%eax ; bye: ; movl %eax , %ebx ; movl $1, %eax ; int $0x80 ; /* exit with status */ .bss ; /* bottom of stack area is for non-threadsafe workspace */ scratchpad: ; .equ cell , 4 ; .skip 4096-cell ; /* room for data stack */ datastack: ; .long 0 ; /* storage for length of loaded program */