Hades logo    Hades applet banner

TAMS / Java / Hades / applets (print version): contents | previous | next

TinyMips - load-byte store-byte instructions

TinyMips - load-byte store-byte instructions screenshot

Description

This applet demonstrates the load-byte and store-byte instructions of the MIPS-I architecture on the TinyMips microprocessor.

Please check the introductory applet for the introduction and description of the TinyMips processor. The hardware structure used for this applet consists of the processor, some glue logic, and a single RAM component that stores both the program and the output data.

The load-byte store-byte demo

Simulations of typical processor workloads indicate that string operations amount for a large fraction of the total runtime, especially for 'commercial' programs like databases or webservers, etc. Therefore, the MIPS designers decided to include special instructions to transfer single bytes (and half-words) between memory and registers into the MIPS instruction set. Without this, any attempt to store a single byte into memory would require a read-modify-write sequence. However, all MIPS arithmetic and logical instructions follow the RISC principles and operate on whole words (32-bit data).

This applet demonstrates the memory accesses generated by the gcc compiler for typical string operations. It also serves as a simple selftest to check that the load-byte and store-byte instructions work on the simulation model of the TinyMips processor and the MipsRAM memory. The basic idea behind the MIPS memory subsystem is to use separate byte-enable signals to indicate which of the four bytes of a 32-bit word are to be written during a write cycle. For the standard 32-bit word-transfers already demonstrated in the previous applets, all four byte-enable signals are asserted (active low). However, during store-byte (or store-halfword) instructions, only one (or two) of the four byte-enable lines are asserted, and the memory subsystem is expected to react accordingly.

Usage

Wait until the applet is loaded. You can now open the memory-editor (via popup > edit) The memory editor highlights the last read operation in green color, and the last write operation in cyan color, which allows you to easily watch the program execution.

If you want to change the simulation speed, just select 'edit' on the clock-generator component, then edit the value of the clock-generator 'period' property, and select 'apply' (and 'ok' to close the clock-generator config dialog). The default clock rate is slow enough to allow you watching the memory accesses during the main loops of the program.

Similarly, open the TinyMips user-interface window (via popup > edit) to watch the current register values.

The binary program running on the processor was compiled and linked with the GNU gcc (2.7.2.3) and binutils cross-compiler toolchain on a Linux x86 host, with the final ELF loading and relocation done via the Hades Elf2rom tool. See

for details. The following listing shows the actual C source code of the program:

/* test mixed integer and char operations on the Hades MIPS processors.
 *
 * Note that the compiler will use load-byte and store-byte instructions,
 * which means that the endianness of the processor matters.
 * Our gcc x86-x86-mips-elf (2.7.2.3) crosscompiler uses little-endian 
 * memory accesses, and the MIPS must be configured correspondingly.
 *
 * When successful, the program writes an array of 256 chars (bytes)
 * with values 00,01,02,...,fe,ff starting at memory address 0x*400
 * (Hades MipsRAM internal address 0x00100), and a second array of
 * 256 bytes with values 03,04,05,...,fe,ff,00,01,02 starting at 
 * memory address 0x*600 (internal address 0x00150).
 * The program then tries to read the first array back and checks
 * the values. If successful, the program writes the magic value
 * 0xcafe0000 into memory address 0x*3ff (0x000ff) and enters an endless
 * loop.
 * When the read-back values don't match, the program writes the value
 * 0xdead0000 and enters an endless loop.
 */


#define BASE  0x00000400
#define OK    (BASE- 8)
#define BAD   (BASE- 12)


static char* hello = "Hello, world!\n\f";



void bad( int c ) {
  int i, *bad;
 
  bad= (int*) BAD;
  *(bad-1) = 0xdead0000 + c;
  for( i=0; ; i++ ) {
    *bad= i;
  }
}


int main( int argc, char** argv ) {
 
  char c, d;
  char *ptr, *ptr2;
  int  *ready;
  int  i,j;


  ptr = (char*) (BASE-32);

  *ptr = 'a';
  *(ptr+1) = 'b';
  *(ptr+2) = 'c';
  *(ptr+3) = 'd';

  // *(ptr+4) = 'e';
  *(ptr+5) = 'f';

  d = *(ptr+3);

  ready = (int*) OK;
  *(ready-12) = 0xbabe0000 | d;
  *(ready-11) = 0x000a1234 | d;

  ptr = (char*) BASE;
  ptr2 = (char*) (BASE+256+64);

  // write sequence of ASCII chars
  c = (char) 1;
  for( i=0; i < 256; i++ ) {
    c = (char) i;
    d = (char) (i+3);

    *(ptr+i)  = c;

    *ptr2 = d;
    ptr2++;
  }

  

  // read them back and compare
  ptr = (char*) BASE;
  for( i=0; i < 256; i++ ) {
    c = (*ptr); 
    if (c != (char)i) {
      bad( i );
    }
    ptr++;
  }

  // success: endless loop
  *(ready+1) = 0xcafe0000;
  for( i=0; ; i++ ) {
    *ready = i;
  }
}

Run the applet | Run the editor (via Webstart)


Impressum | 24.11.06
http://tams.informatik.uni-hamburg.de/applets/hades/webdemos/76-mips/15-lbsb/lbsb_print.html