I talked about how to look at the assembler code and figure out some equivalent C code. Let's start with a fragment from the code that I gave you to run for assignment 1:
... stuff ... la $s0, inbuf loop: lb $s1, 0($s0) add $s0, $s0, 1 beq $s1, 0x0, done beq $s1, 0xa, done ... stuff ... j loop done: ... stuff ...This code is equivalent to:
char inbuf[256]; main() { char *s0; int s1; ... stuff ... s0 = inbuf; for (;;) { s1 = *s0++; if (s1 == 0) break; if (s1 == 0) break; ... stuff ... } ... stuff ... }I also talked more about addressing modes. Suppose we declared the following in C:
struct foo { int i0; char c0; int i1; } farr[100];This is an array of 100 structures, each of which contain as members i0, c0, and i1. The C compiler will lay the memory out as follows:
addr memory fffffffc fffffffd fffffffe ffffffff +--------+--------+--------+--------+ ffff ffff | | | | | | | | | | / / / / / \ \ \ \ \ / / / / / farr[2] abcd ef18 | | | | | +--------+--------+--------+--------+ abcd ef14 | hi i1 | i1 | i1 | lo i1 | abcd ef10 | c0 | pad | pad | pad | farr[1] abcd ef0c | hi i0 | i0 | i0 | lo i0 | +--------+--------+--------+--------+ abcd ef08 | hi i1 | i1 | i1 | lo i1 | abcd ef04 | c0 | pad | pad | pad | farr[0] abcd ef00 | hi i0 | i0 | i0 | lo i0 | +--------+--------+--------+--------+ | | | | | / / / / / \ \ \ \ \ / / / / / 0000 0004 | | | | | 0000 0000 | | | | | +--------+--------+--------+--------+ 00000000 00000001 00000002 00000003(This assumes big-endian, which is how the Suns work.) The high order byte of i0 is placed in address abcd ef00, the next byte is in abcd ef01, etc. Because of word alignment restrictions, i1 is not placed immediately after c0 -- instead, 3 bytes of padding is added, so that i1 will be at a 4-byte boundary (address ends with 0, 4, 8, or c).
Suppose we have a pointer:
struct foo *fptr;which points into an element of the array farr. When you use C code such as
int i; i = fptr->i0;the compiler generates the following assembly code:
lw $s1,0($s0)assuming that $s0 contains the pointer fptr, and $s1 is used to hold the variable i. For
char c; c = fptr->c0;the equivalent assembly code is
lb $s1,4($s0)and for
i = fptr->i1;it is
lw $s1,8($s0)And if we had a c1 declared as in:
struct bar { int i0; char c0, c1; int i1; } barr[100]; struct bar *bptr;the memory would be laid out as
addr memory fffffffc fffffffd fffffffe ffffffff +--------+--------+--------+--------+ ffff ffff | | | | | | | | | | | hi i1 | i1 | i1 | lo i1 | abcd ef04 | c0 | c1 | pad | pad | abcd ef00 | hi i0 | i0 | i0 | lo i0 | | | | | | 0000 0004 | | | | | 0000 0000 | | | | | +--------+--------+--------+--------+ 00000000 00000001 00000002 00000003we would do
char c; c = bptr->c1;as
lb $s1,5($s0)
bsy@cse.ucsd.edu, last updated