Simplifications and abstraction in assembler

  - File and terminal access is abstracted away into small functions
    - Can be replaced depending on the OS (might not have C std lib)
    - Small utility and system functions can be easily translated to
      assembly by hand
  - Moved line buffer in asm.c to global scope to save stack memory
  - Assembler always generates object files. Turning them into something
    else is left to a different program (e.g. linker)