Assembler Directives

Source Code Control

In most modern machines, the code and data must be stored separately. This is not true of the simulator but is true of the SPARC.

In SPARC use

.section ".text"  !the following lines are instructions
.section ".data"  !the following lines are data

Although it is common to have all of the code at the beginning and all of the data at the end, it is preferable in many cases to interleave them, to improve readability. For example,

! Print a heading

      set  head,%o0
      call printf
      nop

! Here's the heading

      .section ".data"  !switch to data
head: .asciz   "The solution is:\n"
      .section ".text"  !switch back to code again

! Now continue processing

      add  %g0,%g0,%L4  !Initialize count to 0.

2. Boundary Alignment

In SPARC, use

.align  N

where N is 2, 4, 8, or 16, to indicate that the next item should be placed at an address that is a multiple of N. Use ".align 4" to align the instructions.

In the simulator, use

DS.W   O

to produce the proper alignment when some code follows the data. The "ORG $1000" directive aligns the first chunk of code. The template does both of these diectives for you. Since data is forced on the correct boundary alignment, there is no need to use this directive with data.

3. Storage Allocation

To allocate uninitialized storage for variables, use

680x0:
   ds.b N ;allocate N bytes of uninitialized storage
   ds.w N ;allocate N words (2N bytes)
   ds.l N ;allocate N longwords (4N bytes)
SPARC:
   .skip N ;allocate N bytes of uninitialized storage

To place particular initial values in memory (constants or initialized variables) use

68000:
   dc.b value,value,... ;Each value occupies 1 byte
   dc.w value,value,... ;Each value occupies 2 bytes
   dc.l value,value,... ;Each value occupies 4 bytes
   dc.b 'characters..'  ;Each ascii character occupies a byte
SPARC:
   .byte  value,value,... ;Each value occupies 1 byte
   .half  value,value,... ;Each value occupies 2 bytes
   .word  value,value,... ;Each value occupies 4 bytes
   .ascii 'characters..'  ;Each ascii character occupies a byte
   .asciz 'characters..'  ;Each ascii character occupies a byte,
                          ;and a null byte (0) is added at the end.

In 680x0 you can also allocate a block of N data items, all of which are initialized to the same Value, using

dcb.b N,Value ;Allocate N bytes, all initialized to Value
dcb.w N,Value ;Allocate N words, all initialized to Value
dcb.l N,Value ;Allocate N longwords, all initialized to Value

4. Symbol Definition

In any assembler, symbols (identifiers) may be defined in two ways:

  1. By using a symbol as a label, it stands for the address into which the following code or data will be placed (the value of the "location counter").
  2. By defining a symbol and giving it a value directly. In 68k use
    symbol: equ value
    and in SPARC use
    symbol = value
    where the "value" may be any constant, or any expression which combines constants to give a constant answer. The character "*"(68k) or "." (SPARC) stands for the address into which the following code or data will be placed (the value of the "location counter").

Example (using 68000 syntax):

ArraySize: equ   10
TheArray:  ds.w  ArraySize  ;allocate space for the array

Heading:   dc.b  'This is a longwinded heading full of junk...'
HdgLngth:  equ   *-Heading

Four symbols are defined here. "ArraySize" has the value 10, "TheArray" has as its value the address of a block of 10 words in memory (which is also an integer value just like 10), "Heading" has as its value the address of a string of characters in memory, and the value of "HdgLngth" is the length of that string.

(using SPARC syntax):

Symbolic constants are not allowed in the expressions in the data section.
	
TheArray:  .skip  4*10 ;Each element takes 4 bytes
size       =      .-TheArray
The last statement is not used much in SPARC.

Standard Library Routines

68K

To call a library routine use:
   jsr    name

Here is a descrition of the standard routines for the 68K.

 Name

Purpose

STOP Halt the program. Always do "JSR STOP" at the end.
NEWLINE Write a newline character. Start a new output line.
DECIN Read a decimal integer, store it in D0.W
HEXIN Read a hexadecimal integer, store it in D0.W
DECIN_LONG Read a decimal integer, store it in D0.L
HEXIN_LONG Read a hexadecimal integer, store it in D0.L
DECOUT Write the integer in D0.W in decimal
HEXOUT Write the integer in D0.W in hexadecimal
DECOUT_LONG Write the integer in D0.L in decimal
HEXOUT_LONG Write the integer in D0.L in hexadecimal
STROUT Write the string whose address is in A0, and whose length is in D0.W
STRIN Read in a string of characters into a "buffer" (place in memory) whose address is in A0. Reading stops when a newline character is read (it is stored in the buffer, too). The number of characters actually read (including a newline, if any) is returned in D0.W.
PUTCHAR Write out the character in D0.b
GETCHAR Read in the next character and put it in D0.b

In the simulator, it is a convention (i.e. you must) to have a comment statement showing which routines are used from the template. Also the program should be put in the template.

The parameters (if any) are passed by placing them in registers D0 and/or A0 before the JSR statement is executed. The result if any, is returned in register D0. The template has a description of each of the routines in it.

SPARC

It is good usuage to comment which routines are being used from the MASlib.c. USE:
CALL    NAME
to call any subporogram from the standard C-language library. Before execution of the "call", place the parameters in registers %o0, %o1,..%o5. This will handle 97% of calls. The other 3% we will deal with later. Remember that "call" is a branch instruction and it has a delay slot so fill it. Remember to assemble your program properly use:
  cc  Mycode.s MASlib.c

Here is a short description of the available routines:

 Name

Purpose

newline Write a newline character. Start a new output line.
decin Read a decimal integer, store it in %o0
hexin Read a hexadecimal integer, store it in %o0
decin_long Actually the same as decin. Provided for consistency with MAS.
hexin_long Actually the same as hexin. Provided for consistency with MAS.
decout Write the integer in %o0 in decimal
hexout Write the integer in %o0 in hexadecimal
decout_long Actually the same as decout. Provided for consistency with MAS.
hexout_long Actually the same as hexout. Provided for consistency with MAS.
strout Write the string whose address is in %o0. Write characters until a null character (ascii code 0) is encountered.
strin Read in a string of characters into a "buffer" (place in memory) whose address is in %o0, and whose length is in %o1. Reading stops when a newline character is read (it is stored in the buffer, too), or when the buffer is full. The number of characters actually read (including a newline, if any) is returned in %o0.
putchar Write out the character whose ascii code is in %o0
getchar Read in the next character and put it in %o0. EOF is indicated if %o0 = 0xFFFFFFFF = -1.