Chapter 11 - Running Programs

Running Programs (see section 3.5.2 of your text)

The starting address is set by the assembler or the linker.
The loading address is set by the linker.

The Program Counter (PC) must be set before you can run a program.

You can do this in the debugger in several ways:

  1. Memory Register @PC=1000h
    (You cannot use $1000 in the debugger)
  2. Program Step From 1000h <return> Program Step

You can also automatically set the PC in the assembler:
<label> <your code begins here>
rest of your program
end <label>
where <label> is any name you want. It will be used to set the initial PC value.

Fetch and execute for a simple example

Initially:

Fetch:

You can look up how long it takes instructions to execute:


More detailed example:

From Table D.2, it takes 16 clock cycles (4 reads/0 writes) to execute.

You want fast instructions whenever possible, i.e. no extension words.

Example:
MOVEQ does not use an extension word.


Section 5.1: The Condition Code Register (CCR)


The System Part of the SR

Any unimplemented byte is always set to zero!
You can always read the entire SR, but you can only modify the system byte of the SR in supervisor mode.

Examples:

Even a MOVE instruction affects the status register:

Examples:

MOVE.W   LENGTH,D1
if (LENGTH) = 0 then (Z)-->1

MOVE.B   #$FF,D1
(Z)-->0, (N)-->1

How an instruction affects the SR is shown in the Programmer's Reference Manual and on the Programmer's Reference Card.

Examples of status flags (all word length)

Consider an add instruction of the form
ADD.W D0,D3

The result 129 is out of range for a signed 8-bit number. As a result, the sign of the result does not match that of the operands, and signed overflow occurs.

The signs match so no signed overflow occurs.

The result -132 is out of range for a signed 8-bit, so the signs don't match and signed overflow occurs. In addition, a carry occurs.

The same analysis can be applied to subtraction:

SUB.W D0,$1200
where (D0) = $0F13 and ($1200) = $01C8

Note that, since the result is negative, this would be sign-extended to long word if the instruction length were .L.


Simple assembly language example

(Program 4.1 of text)

field#1   field#2   field#3
          ORG       $1000       ;start program at this memory location

CODED INSTRUCTIONS
MAIN:     MOVE      DATA,D5     ;get first number, use symbol for it
          ADD       NEXT,D5     ;add NEXT to D5
          MOVE      D5,ANSWER   ;save result
          TRAP      #0          ;this will stop the program,
                                ;but will not do what it is
                                ;supposed to do

          ORG       $1200

DATA DECLARATIONS
DATA:     DC        $1235       ;put $1235 into location
NEXT:     DC        $4321       ;put $4321 into location
ANSWER:   DS        1           ;reserves one word of memory 
                                ;could also have used DC.W $0

          END       MAIN        ;stop assembler


Notes:
  1. Program in text uses HEXIN and HEXOUT. These do not work in our debugger. You will be introduced to their equivalent in Lab #3.
  2. Use of symbols in programs is highly recommended to make them more readable.
  3. Symbol table contains a symbol field, type field, and a value field.
  4. Use of colons (:) following labels is optional if the label's name begins in column 1.
  5. Use of the semicolon to begin a comment is also optional.

You can write programs in machine code but that is

So, we use programs to make the process more efficient.

Cross-assemblying is when you assemble on another machine, say an 80286, using a program to generate 68000 machine code.

Down-line loading is when you transfer object code between machines. When you transfer your code to the in-circuit emulator, you are downloading.

Example of mnemonic instruction:

It would take a great deal of effort to calculate addresses all the time, so a good assembler allows you to assign names to program locations and constants.

For example,
MOVE.W D5, DATA
instead of
MOVE.W D5,$1200

Section 4.2 of your textbook describes program organization.

Labels are implied if they precede a valid instruction code and begin in column 1. Labels are defined if they are followed by a colon.

Implied:
LOOP MOVE.W D5,DATA
Defined:
LOOP: MOVE.W D5,DATA

Comments are implied if they follow a valid instruction on a line. In some assemblers they must be preceded by a semi-colon (;) or asterisk (*). Comments are defined if they begin with a "*" in column 1.

Assembler directives tell the assembler to perform a support task, such as beginning the program at a certain memory location.

ORG
Tells the assembler where that section of the program is to go in memory.
END
End of entire program (including data). Put the starting label after the END for automatic loading of the starting PC.
DC
Puts a set of data into memory (Define Constant).
DS
Reserves specified memory locations (Define Storage).

Many assembler directives and instructions can operate on bytes, words, or long words. What is to be acted on is indicated by a prefix or suffix.

.B
Byte length operations.
.W
Word length operations (almost always assumed).
.L
Long word operations.
$
Indicates a hex number; decimal is assumed otherwise (does not work in debugger).
h
Follows number in debugger to indicate hex. Hex constants in debugger must begin with a number.
#
Precedes an immediate constant.
D0-D7
Data registers.
A0-A7
Address registers.

Some assemblers will print out a symbol table which will list all variables, including labels, and their values.

The EQU directive (F&T, section 6.3.2)

Directly puts something in the symbol table. Such a symbol is not a label, but a constant! Use EQU to define often-used constants.

LENGTH    EQU     $8
MASK      EQU     $000F
DEVICE    EQU     $3FF01

You can also use the format
LABEL   EQU     *

which enters the current value of the PC as its value.

SET acts the same as EQU, but you can redefine the value of the variable later in your program.

XREF tells the assembler/linker that the following symbol(s) are defined in another program module (file). XDEF tells the assembler/linker that the following symbol(s) are defined in this program module for use (reference) by another program module (described on p.204-205 of F&T).

DATA      EQU     $6000
PROGRAM   EQU     $4000

ORG       DATA
                              TABLE OF FACTORIALS
FTABLE    DC      1           0!=1
          DC      1           1!=1
test      DC      2           2!=2
          DC      6           3!=6
          DC      24          4!=24
          DC      120         5!=120
          DC      720         6!=720
          DC      5040        7!=5040
VALUE     DS.B    1           input to factorial function
          DS.B    1           align on word boundary
RESULT    DS.W    1           result of factorial



ORG       PROGRAM
main
                              PUT TABLE BASE ADDRESS IN A0
          NOP
          NOP
          MOVEA.W #FTABLE,A0  gets $6000
          MOVEA.W FTABLE,A1   gets $1
          MOVE.W  #FTABLE,A2  gets $6000
          MOVE.W  #FTABLE,D0  gets $6000
          MOVE.W  FTABLE,D1   gets $1

          MOVE.W  test(A0),D3 test displacement


          MOVE.W  #5,VALUE    input to fact is 5

fact      MOVE.W  VALUE,D5    get input
          ADD.W   D5,D5       double for word offset
          LEA     FTABLE,A3   get base address
          MOVE.W  0(A3,D5),D6 get result
          MOVE.W  D6,RESULT   output

          END main


How to run your program

as68k Example1
Assumes a file with the full name Example1.s is present. Produces an output Example1.o. as68k is a two-pass assembler. The first pass reads the entire program, computes all instruction addresses, and assigns addresses to labels. The second pass converts all instructions into machine code using the label addresses.

ld68k -o Example1 Example1
The first file name following the -o is the output file which will automatically be named Example1.x; the second file name is the input which is assumed to be Example1.o.

db68k Example1
This will run the debugger, using the file Example1.x.

Remember, the Program Counter (PC) must be set before you can run a program.

You can do this in the debugger in several ways:

  1. Memory Register @PC=1000h
    (You cannot use $1000 in the debugger)
  2. Program Step From 1000h <return> Program Step

You can also automatically set the PC in the assembler:
<label> <your code begins here>
rest of your program
end <label>
where <label> is any name you want. It will be used to set the initial PC value.

Some useful debugger commands

Debugger Quit Yes <return>
Quits the debugger.

Window Active Assembly Registers <return>
Removes the journal window and shows the Status Register.

Program Step From 1000h <return>
Resets the code window to $1000 and executes the instruction at $1000. Note that only one instruction is executed.

Program Step <return>
Executes the instruction currently highlighted. This command following the initial Program Step From 1000h would execute the instruction at $1006.

Memory Register @PC=1000h <return>
Sets the current value of the PC to $1000; i.e. this is the next instruction to be executed.

Memory Register @A3=1000h <return>
Sets the current contents of A3 to $1000. Can be used for all registers including SR.

Expression Monitor Value @A1 <return>
Continuously displays the value of A1 in the monitor window.

Note: The @ indicates a reserved symbol such as the name of a data or address register, the PC, or the SR.


Comments on MC68000 instructions in Lab #2

These instructions operate on data registers
        MOVE.W  #$FFFE,D0     ;you will get different results
                              ;if you use .L instructions
        ADD.W   #1,D0
        ADD.W   #1,D0
        ADD.W   #$FFFE,D0
        ADD.W   #2,D0

These instructions operate on address registers
        LEA     $2000,A0
        MOVE    #$2000,A1     ;this is not an allowed instruction,
                              ;assembler will automatically
                              ;convert to MOVEA
        MOVE    D0,(A0)       ;address register indirect

If you look at the MOVE instruction, An is not allowed. You must use a MOVEA which can only have an address register as a destination. The instruction
MOVEA <ea>,A1
is the only form of the MOVE that can put data into an address register. The size of the operator can be .W or .L Word size operands are sign-extended to 32 bits before any operations are done.

The LEA instruction is subtly different than a MOVEA; it computes <effective address> and puts that into An. Only a long form of the instruction is allowed.

MOVEA converts addresses into constants. LEA generates position independent code using PC relative address modes and is better for position independent code. MOVE D0,(A0) moves the contents of D0 into the address location stored in A0.


Next Section: Chapter 12 - Assembly Examples
Previous Section: Chapter 10 - Programmer's Reference Manual
EEAP 282 Class Notes Table of Contents


-- aurora@po.cwru.edu -- About this server -- Copyright 1992, F. Merat