/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ │vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ ╞══════════════════════════════════════════════════════════════════════════════╡ │ Copyright 2022 Justine Alexandra Roberts Tunney │ │ │ │ Permission to use, copy, modify, and/or distribute this software for │ │ any purpose with or without fee is hereby granted, provided that the │ │ above copyright notice and this permission notice appear in all copies. │ │ │ │ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ │ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ │ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ │ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ │ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ │ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ // @fileoverview Binary Lambda Calculus Virtual Machine // In a 521 byte Linux x64 ELF executable // // @see https://tromp.github.io/cl/Binary_lambda_calculus.html // @see https://www.ioccc.org/2012/tromp/hint.html #define TRACE 0 // enable ./trace.sh support #define STACK 31 // how many bits of stack memory #define TERMS 5000000 // number of words of bss #define sz (1< 31 xor %eax,%eax push %rax # calloc() on stack lool push %rax push %rax push %rax #else push $0 push $0 #endif mov %rsp,frep # allocate heap on stack lool 1: inc idxd xchg V(contp),NEXT*sz(frep) # get closure from free list xchg V(contp),V(frep) I(inc) REFS*sz(contp) # save machine state I(inc) REFS*sz(envp) mov V(envp),ENVP*sz(contp) 2: add V(idx),R(cx) mov R(cx),TERM*sz(contp) 77: jmp Eval Exit: mov sz(mem,idx,sz),%edi pushpop 60,ax # __NR_exit syscall Read: call GetBitAddr test bitsb,bitsb lea 1(bitsd),bitsd jle Expand xor %esi,%esi # Copy(0,6) pushpop 7,cx call Copy movb $4+8*(7+4)+4,-5*sz(%rdi) // jmp Expand Expand: push %rsi # save 1 0: test bitsb,bitsb jz 1f xor %eax,%eax call GetBitAddr # Copy[0,9] w/ GetBit() setnc %al push $0 # save 2 push $10 # save 3 jmp 2f 1: xor %eax,%eax # Copy[7,9] w/ 0 push $7 # save 2 push $3 # save 3 2: pop %rcx # rest 3 pop %rsi # rest 2 push %rax # save 4 call Copy pop %rax # rest 4 I(stos) pop %rax # rest 1 test %al,%al jz 77b push bits jmp 0b .globl ehdr .globl _start .type kRom1,@object .type kRom2,@object .type kRom3,@object .type ehdr,@object .type ehdr2,@object .type ehdr3,@object .type phdrs,@object .type phdrs2,@object .weak filesz .weak memsz