CSE 30 -- Lecture 6 -- Oct 16


Homework 3, base conversions, due before class Wed, Oct 23:
  1. 210112 (base 3) = ? (base 9)
  2. 825701 (base 9) = ? (base 3)
  3. 537 (base 9) = ? (base 10)
  4. (17)(7)(20) (base 25) = ? (base 5)
  5. 65213 (base 7) = ? (base 49)
Also, you need to explain how you obtained the answer that you give. You are allowed to refer to prior explanations in your explanation of later conversions.

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 00000003
	
we would do
char	c;

c = bptr->c1;
as
		lb $s1,5($s0)

[ CSE 80 | ACS home | CSE home | CSE calendar | bsy's home page ]
picture of bsy

bsy@cse.ucsd.edu, last updated Wed Oct 16 22:37:44 PDT 1996.

email bsy