3. Data Storage Directives

Part of the SMAL Manual
by Douglas W. Jones
THE UNIVERSITY OF IOWA Department of Computer Science

Index

  1. Storing Bytes
  2. Storing Halfwords
  3. Storing Three-quarter Words
  4. Storing Words
  5. Storing Text

SMAL32 supports several directives to store data in memory; it is important to remember that all of these are used to store constant values in memory at assembly time. That is, ultimately, the only thing an assembler does. The program is a sequence of constant-valued machine instructions, and the the initial values of global variables are additional assembly-time constants. Newcomers to assembly language programming frequently confuse assembly-time storage directives with machine instructions for updating the values of variables at run time.

All of the data storage directives operate relative to the location counter, the memory address where the next byte is to be assembled into memory. The location counter may be an absolute address, or it may be relative to some relocation base (an external symbol, see Chapter 4) known to the linker (See Chapter 8).

When data is assembled into memory, the location counter is incremented by one for each byte assembled, and the programmer may also adjust the location counter directly (See Section 2.2).

3.1. Storing Bytes

<symbolic directive> ::= B <expression> { , <expression> }

The B directive assembles a byte (8 bits) into memory, incrementing the assembly location counter by 1. Therefore, successive B directives load data into successive bytes of memory. B directives are most commonly used to initialize character variables and individual components of arrays of characters. If multiple operands are included, the additional operands are treated as if they were processed by new B directives on following lines.

The following fragment of an assembly listing demonstrates the use of this directive for various purposes:

 00000D: 01                  8        B     1
 00000E: 02  03              9        B     2, A
 000010: 0A                 10        B     10
                            11  A     =     3
 000011: 10                 12        B     #10
 000012: 20                 13        B     " "
 000013: 41  42  43  00     14        B     "A", "B", "C", 0

3.2. Storing Halfwords

<symbolic directive> ::= H <expression> { , <expression> }

The H directive assembles a halfword (16 bits) into memory, incrementing the location counter by 2. Therefore, successive H directives load data into successive halfwords of memory. H directives are most commonly used to initialize short integer variables and individual components of arrays of short integers. If multiple operands are included, the additional operands are treated as if they were processed by new H directives on following lines.

The following fragment of an assembly listing demonstrates the use of this directive for various purposes:

                            15  .     =     .+(ABS(.)&1)  ; align 2
 000018: 0001               16        H     1
 00001A: 0002  0003         17        H     2, B
 00001E: 0400               18        H     1024
                            19  B     =     2#11
 000020: FFFF               20        H     -1
 000022: 4120  0000         21        H     "A ", 0
 000026: 0041               22        H     "A"

When storing halfwords, the H directive does not force alignment of the location counter to an even address. The programmer must force alignment if it is needed. Line 15 illustrates this. On most computers, access to aligned halfwords, those that begin on even addresses, is faster than access to non-aligned ones. On some machines, variables stored at non-aligned addresses are difficult to load or store. (See Section 2.2 and the ALIGN macro in Section 6.4.)

Programmers should use extreme care when using quoted strings (see Section 1.5) as arguments to the H directive. This works only for one and 2 character strings. Furthermore, the values stored by the H directive may differ from the values stored by a sequence of B directives or by an ASCII directive. This will cause trouble when the SMAL assembler is used on computers where the low byte of each halfword is considered to be the first byte of that halfword.
 

3.3. Storing Three-quarter Words

<symbolic directive> ::= T <expression> { , <expression> }

The T directive assembles a three-quarter word (24 bit) quantity into memory, incrementing the assembly location counter by 3. This directive is included for completeness. When storing three-quarter words, beware that the T directive does not force any alignment of the location counter prior to assembling its operand, and that the assembly of three-byte objects into memory usually guarantee that the location counter will not be aligned afterwards.

3.4. Storing Words

<symbolic directive> ::= W <expression> { , <expression> }

The W directive assembles a word (32 bits) into memory, incrementing the assembly location counter by 4. Therefore, successive W directives load data into successive words of memory. W directives are most commonly used to initialize integer variables and individual components of arrays of integers. If multiple operands are included, the additional operands are treated as if they were processed by new W directives on following lines.

Note that the location counter changes occur after expression is evaluated, so that, for example, W . will store a pointer to itself, not a pointer to the following word.

The following fragment of an assembly listing demonstrates the use of the W directive:

                            23  .     =     .+(ABS(.)&1)  ; align 2
                            24  .     =     .+(ABS(.)&2)  ; align 4
 000028: 00000001           25  C:    W     1
 00002C: 0000002C           26        W     ., C
 000030: 00000028
 000034: FFFFFFFF           27        W     #FFFFFFFF
 000038: FFFFFFFF           28        W     32#3VVVVVV
 00003C: FFFFFFFF           39        W     -1
 000040: 30313233           30        W     "0123"

When storing words, note that the W directive does not force alignment of the location counter to an whole-word address. Thus, all of the warnings given above for halfwords apply here as well. (See Section 2.2 and the ALIGN macro in Section 6.4.)

Programmers should use extreme care when using quoted strings (see Section 1.5) as arguments to the W directive. This works only for one through 4 character strings. Furthermore, the values stored by the W directive may differ from the values stored by a sequence of B directives or by an ASCII directive. This will cause trouble when the SMAL assembler is used on computers where the low byte of each word is considered to be the first byte of that word.

3.5. Storing Text

<symbolic directive> ::= ASCII <quoted string> { , <expression> }

The ASCII directive assembles the consecutive ASCII characters of a quoted string (see Section 1.5) into consecutive bytes if a series of B directives had been used, one per character. Arguments to an ASCII directive following the initial quoted string may be additional quoted strings or expressions; if the latter, they are evaluated and treated as if they occurred as arguments to a B directive.

The following sample assembly listing demonstrates the use of this directive:

 000044: 61                 31        ASCII "a"
 000045: 62  63             32        ASCII "bc"
 000047: 64  65  66         33        ASCII "def"
 00004A: 67  68  69  00     34        ASCII "g", "hi", 0

Use of the ASCII directives usually leaves the loction counter unaligned unless care is taken to store multiples of 4 bytes or multiples of 2 halfwords. (See Section 2.2 and the ALIGN macro in Section 6.4.)

Note that use of quoted strings constants as arguments to W or H directives will not necessarily produce the same result in memory as would result from using the ASCII directive. This will cause trouble when the SMAL assembler is used on computers where the low byte of each word or halfword is considered to be the first byte of that halfword.