========================= Programming with Assembly ========================= * With the use of an assembler, generating the machine code for the ESAP system becomes easier * Once the assembly language is written, it can be *assembled* into the machine code, that can be loaded into RAM Revisiting Problems =================== * Consider the problems already solved with machine code hex files * Instead of writing machine code, the assembler allows one to write in the assembly language * The mnemonics can be used, making programming easier and making the program much easier to understand * The assembly language is then assembled, with the assembler, to the machine code * This machine code can then be loaded into the ESAP system for execution Arithmetic ---------- * Consider the problem of outputting the result of the calculations ``31 + 32`` and ``31 - 32`` * This problem was already discussed in the machine code topic .. list-table:: Arithmetic Program :header-rows: 1 :align: center * - Assembly - Machine Code * - .. literalinclude:: arithmetic_31_32.esap :language: text :lineno-match: - .. literalinclude:: arithmetic_31_32.hex :language: text :lineno-match: * Above is a table comparing the assembly language program and the corresponding machine code * This machine code was generated by the assembler * The line numbers do not align here as the hex file requires the ``v2.0 raw`` line * Notice that the data (``31`` and ``32``) is stored at the end of RAM * This is not a requirement * Although the Von Neumann architecture has instructions and data share the same memory space * It is often desirable to try to physically separate instructions and data in some way * May help with interpretability of programs * Also notice the ``NOOP``\s filling the space between the instructions and data * The assembler ignores white space, so any empty RAM addresses need to be explicitly set * This was done here to facilitate physically separate instructions and data * Technically anything could be put in these addresses, data or instruction, as they follow ``HALT`` * The system would never be able to run these RAM addresses * However, to make the program as clear and intentional as possible, ``NOOP``\s were used * Entering the data ``0x00`` would also work, as it is the same bit pattern as ``NOOP`` * However, again, to make the assembly program more clear, ``NOOP`` is used * Finally, notice the use of hex values to specify addresses, but decimal for the data * All values are in hex except ``31`` and ``32`` * This is not a requirement as the assembler converts everything to the same machine code, regardless of base * This decision was made here to help provide clarity to the program Counting -------- * Below is the program to count by ones forever * Like the above arithmetic problem, this was already discussed in the machine code topic .. list-table:: Counting Forever Program :header-rows: 1 :align: center * - Assembly - Machine Code * - .. literalinclude:: counting_forever.esap :language: text :lineno-match: - .. literalinclude:: counting_forever.hex :language: text :lineno-match: Check 10 -------- * Below is the program to check if a number is ``< 10`` * This was discussed in the conditions and conditional jump topics .. list-table:: Check ``< 10`` Program :header-rows: 1 :align: center * - Assembly - Machine Code * - .. literalinclude:: check_10.esap :language: text :lineno-match: - .. literalinclude:: check_10.hex :language: text :lineno-match: * In the above program, like before, the value to check is stored in address ``0xF`` * To check if a different value is less than 10, one would have to alter the code * Here, addresses ``0xD`` and ``0xE`` store the value to be output based on if the value is less than 10 or not * Storing the value ``0`` is not strictly necessary here for several reasons, but it does help with intentionality * It's not needed because the ESAP system in Digital starts with a ``0`` in the output register * Further, the ``NOOP``\s are ``0``, so any of those addresses could be used * Again, ``NOOP``\s are included to allow separation of the instructions and data Count to 10 =========== * With the use of the assembler, the programs are easier to write and understand * This is important as solving complex problems is challenging enough as is * The tedium of machine code only makes solving complex problems that much more difficult * Consider the more complex problem of counting to 10 * Output the numbers ``1`` to ``10`` * This may sound simple, but it is challenging when programming at such a low level * This problem combines two of the previous problems * Counting forever * requires looping * Checking if a value is less than 10 * requires branching * Below is the assembly and corresponding machine code for a solution to this problem .. list-table:: Count to 10 :header-rows: 1 :align: center * - Assembly - Machine Code * - .. literalinclude:: counting_10.esap :language: text :lineno-match: - .. literalinclude:: counting_10.hex :language: text :lineno-match: * Notice how the count value must be preserved before the subtraction can happen * Here, the ``JMPS`` instruction is used like a kind of while loop * While the count is less than 10, jump * Note that, when running the program, it will appear to count ``0`` -- ``10`` * This is due to the simulator and how the output register starts with a ``0`` * Additionally, the starting instructions of ``LDAD 0`` and ``SAVA 0xF`` could have been excluded * The simulator initializes RAM with ``0``\s * However, having clear and intentional code is preferred For Next Time ============= * Something?