## Octal "assembler", based on osm.c, osm[abc].s, and osmb.s; buffering .globl _start _start: mov $output, %edi # output pointer reset: xor %esi, %esi # flag for whether we have data xor %ebp, %ebp # the data we maybe have next: push %esi # stack balance, also zero the buffer xor %eax, %eax mov $3, %al # __NR_read xor %ebx, %ebx # fd = stdin, 0 mov %esp, %ecx # buf on stack xor %edx, %edx # count = inc %edx # 1 int $0x80 # system call, results in %eax dec %eax test %eax, %eax # if not 1: jnz end # bail out pop %eax # fetch character read sub $'0, %eax cmp $7, %eax ja emit # if non-digit, emit buffered byte if any shl $3, %ebp # otherwise shift to make space for digit inc %esi # and set flag or %eax, %ebp jmp next emit: test %esi, %esi # Do we have buffered data to emit? je ops mov %ebp, (%edi) inc %edi ops: cmp $('| - '0), %eax # was the character a |? jne reset # if so, OR the last two bytes: dec %edi mov (%edi), %dl or %dl, -1(%edi) jmp reset end: xor %eax, %eax mov $4, %al # __NR_write xor %ebx, %ebx # fd = inc %ebx # stdout, 1 mov $output, %ecx # buf = output mov %edi, %edx # count = output pointer sub %ecx, %edx # - buf int $0x80 xor %eax, %eax # __NR_exit = inc %eax # 1 int $0x80 .bss output: .fill 65536, 1, 0