Memory Access in SAL

Tom Kelliher, CS 220

Nov. 10, 1997

Announcements

I encourage you to write your assembly from your pseudo-code, not the other way around.

Assignment

Memory as an Array

  1. Memory is a 1-D array of bytes.

  2. Usually, bytes and words are addressable (e.g., bytes are not addressable on the ALPHA, but they have addresses).

  3. The SAL model:
    m:          .byte size_of_memory
    
    ( .space is used to allocate bytes)

  4. How do we access ``raw memory'' in SAL?
    1. m[address]: byte access.

    2. M[address]: word access. address must be aligned.

  5. How are high-level data structures mapped onto memory, the lowest-level data structure? Consider:
    1. Array.

    2. Struct.

    3. Functions???

Definitions:

  1. Memory cell: the smallest unit of addressable storage, usually a byte.

  2. Byte addresses vs. word addresses:
    1. Big-endian:

    2. Little-endian:

      Note that word addresses increase by 4.

  3. Word accesses must be aligned on 0 mod 4 boundaries.

Memory Accessed by Byte

C++ indexed example:

char line[80];
int i;

i = 0;                    // 0 is index of first element of line
cin >> line[i];           // read a character into first element of line
while (line[i] != '\n')   // read characters until end of line is reached
{
   ++i;                   // increment to index of next element of line
   cin >> line[i];        // read next character
}

++i;                      // tack on a null character
line[i] = '\0';

i = 0;                    // print the line just read
while (line[i] != '\0')
{
   cout << line[i];
   ++i;
}

  1. Remember: line[i] = *(line + i * sizeof(char)).

  2. line = &line[0].

  3. Base address, index.

C++ pointer example:

char line[80];
char *cp;

cp = line;            // cp points to first element of line
cin >> *cp;           // read a character into first element of line
while (*cp != '\n')   // read characters until end of line is reached
{
   ++cp;              // increment pointer to next element of line
   cin >> *cp;        // read next character
}

++cp;                 // tack on a null character
*cp = '\0';

cp = line;            // print the line just read
while (*cp != '\0')
{
   cout << *cp;
   ++cp;
}

SAL example:

  1. la corresponds to &.

  2. m[cp] corresponds to *cp.

  3. SAL code:
                   .data
    line:          .byte '\0':80           # note how array declared
                                           # initialization value not too
                                           # important
    cp:            .word
    
                   .text
    __start:       la cp, line
                   get m[cp]
    while1:
                   beq m[cp], '\n', ewhile1
                   add cp, cp, 1
                   get m[cp]
                   b while1
    
    ewhile1:
                   add cp, cp, 1
                   move m[cp], '\0'
    
                   la cp, line
    while2:
                   beq m[cp], '\0', ewhile2
                   put m[cp]
                   add cp, cp, 1
                   b while2
    
    ewhile2:
                   done
    

Memory accessed by Word

  1. int = one memory word.

  2. Use M rather than m.

  3. Remember, word addresses increase by 4.

A SAL program to read 10 ints, sort them into ascending order, and print the sorted list:

               .data
data:          .word 12:10
ptr:           .word
nptr:          .word
i:             .word
k:             .word                   # don't use j
temp:          .word
prompt:        .asciiz "? "
nl:            .asciiz "\n"

               .text
__start:
               la ptr, data
               move i, 10
while1:                                # read 10 ints
               beqz i, ewhile1
               puts prompt
               get M[ptr]
               sub i, i, 1
               add ptr, ptr, 4
               b while1

ewhile1:
               move i, 9
while2:                                # outer loop of bubble sort
               beqz i, ewhile2
               la ptr, data
               mul temp, 8, 4
               add ptr, ptr, temp      # ptr points to next to last
                                       # element in data
               move k, i

while3:                                # inner loop of bubble sort
               beqz k, ewhile3
               add nptr, ptr, 4        # nptr points to next element
                                       # beyond ptr
                                       
if1:                                   # compare & swap
               ble M[ptr], M[nptr], eif1
               move temp, M[ptr]
               move M[ptr], M[nptr]
               move M[nptr], temp
eif1:
               sub k, k, 1
               move nptr, ptr
               sub ptr, ptr, 4
               b while3
ewhile3:
               sub i, i, 1
               b while2
ewhile2:





               la ptr, data
               move i, 10
while4:                                # write 10 ints
               beqz i, ewhile4
               put M[ptr]
               puts nl
               sub i, i, 1
               add ptr, ptr, 4
               b while4

ewhile4:
               done
Note: this will ``sorta'' work if you use m rather than M.

Multi-Dimensional Arrays

Consider the two-dimensional array:

int data[3][4];
How much storage to allocate?

Conceptually:

How is it mapped onto the 1-D memory?

  1. Row major order:

    1. C stores arrays in row major order.

    2. Address of data[i][j]:
      &data[i][j] = data 
                  + i * (# of columns) * (sizeof(data element))
                  + j * (sizeof(data element))
      
      # of columns = length of row.

  2. Column major order:

    1. FORTRAN stores arrays in row major order.

    2. Address of data[i][j]?



Thomas P. Kelliher
Sun Nov 9 18:31:06 EST 1997
Tom Kelliher