Getting started with M68K

The Motorola 68000 the way this editor runs it, the registers and memory it works with, and how a program is written down. It ends with a first program whose answer you read in the registers panel.

Assembly basics went through registers, memory, branching and the stack once, using whichever language made each point clearest. From here on there is one language, the M68K.

The machine

M68K is short for the Motorola 68000, a family of CPUs. It works with:

  • Eight data registers, d0 to d7, 32 bits each. Numbers live here.
  • Eight address registers, a0 to a7, also 32 bits. Addresses live here, and a7 is the stack pointer, which you can also write as sp.
  • Memory, one large array of bytes. In this editor it runs from $000000 to $FFFFFF, so an address is 24 bits.
  • Five flags, X, N, Z, V and C, in a register of their own. Comparisons and most arithmetic write them, and the branch instructions read them.

The registers panel next to every program on this page lists all sixteen. The two kinds are not interchangeable, some instructions take only one of them. For example lea, which loads an address, writes an address register and nothing else.

The M68K is big endian: the most significant byte of a number sits at the lowest address, so a long you wrote as $12345678 reads left to right in memory as 12 34 56 78.

The simulator

There is no real 68000 in your browser, there is a simulator, and this one follows EASy68K. Printing, reading input and drawing go through the instruction trap #15, which is taught in the "Talking to the outside world" module of this course. Until then, programs show what they did in the registers and the memory.

How a program is written down

A line is a label, an instruction, a directive, a comment, or nothing.

  • A comment starts at a ; and runs to the end of the line. A * in the first column comments out the whole line, which is what you will see used for headings inside a program.
  • A label goes at the start of the line and ends with a colon: start:. It is just a name for the address of whatever comes next, code or data. The colon is required.
  • A directive is a line addressed to the assembler instead of the CPU. org says where in memory the code goes, dc writes data there, equ gives a number a name. They get a lecture of their own, "org, equ, dc and ds", later in this course.
  • Everything else is indented, one instruction per line. Four spaces is what these courses use.
  • Case does not matter. MOVE.L D0, D1 and move.l d0, d1 are the same instruction. We write lower case.

Numbers can be written in four bases, and a # in front means the number itself:

writtenmeans
100decimal 100
$64hex, the same 100
%1100100binary, still 100
@144octal, still 100

move.l #$2000, d0 puts the number $2000 in d0. Drop the # and move.l $2000, d0 reads the four bytes at address $2000 and puts those in d0 instead. One character makes two completely different instructions.

Most instructions also carry a size, which says how much of the register or of memory they touch. .b is one byte, .w is two (a word), .l is four (a long). Leave it off and you get a word, which is a good reason to always write it.

Your first program

This one puts two numbers in registers and adds them. Press Build, then Run, and read the answer in d0 in the registers panel.

move.l #10, d0 writes the number 10 into all four bytes of d0, and the line under it does the same with 32 and d1. add.l d1, d0 adds the two registers and leaves the answer in d0, because on the M68K the operand on the right is the destination, the one that gets written. So d0 ends at 42 and d1 is still 32.

Build assembles what you wrote and points the simulator at the first instruction, Run runs the program to the end, and Step runs one instruction at a time.

Nothing in the program says "stop". The simulator ends a program when there is no next instruction to run, which here is the end of what you wrote.

Try changing add.l d1, d0 to add.l d0, d1 and see the answer come out in d1 instead.

Sizes in the registers panel

A size touches the low end of the register and leaves the rest of it alone. Build this one and press Step four times, keeping an eye on d0 in the registers panel.

Try putting move.b #$11, d0 back at the end and see that $33333333 becomes $33333311, not $00000011.

The flags panel

The flags sit just above the registers. cmp subtracts its first operand from its second, throws the answer away and keeps only what the answer did to the flags. Z goes to 1 when the two were equal, which is what beq and bne read.

Step through it and watch Z: it goes to 1 after the first cmp and back to 0 after the second one.

Your turn

Two instructions. Leave $FF in the lowest byte of d0 without disturbing the three bytes above it, and put 100 in d1. The test starts d0 at $12345678, so a correct answer leaves it at $123456FF. Write your two instructions and press Test.

Show solution