|
|
c m s c 311
s u m m e r 2 0 0 2 |
Due Date Friday, July 12, 11:59 PM (just before midnight)
Posted: July 6, 2002
Additions
In this project, there are several goals:
Please note that *all* programming projects in this course (including this one) are to be done independently or with the assistance of the instructional staff of this course only, unless otherwise specified IN PRINT by official webpages.
Please review the policies outlined on the class syllabus concerning the use of class computer accounts and concerning the University's Code of Academic Integrity. The instructors of this course will review the programs submitted by students for potential violations of the Code of Academic Integrity and if it is believed that a violation has occurred it will be referred to the Office of Judicial Programs and the Student Honor Council.
Hardcoding is considered a violation of academic integrity
If we had had even more time, we would begin to do some microprogramming. This involves storing control signals in a ROM, and sending control signals to various registers and getting data to move around.
That would be very interesting, but quite time-consuming. But just in case you were curious, that's where we would have gone.
This saves the current program loaded to a file called filename.
filename either ends in .bin or it doesn't. If
it does, then don't change the name of the file. If it doesn't,
then save it with a .bin extension. Thus, if the person types in:
save-binary my_asm
Then, you save it as my_asm.bin.
If no program is loaded, print a message:
Sorry, no program is loaded.
This will print the current program loaded in "hex" format. Again, if a program has not been loaded, print the previous error message.
This is extra credit. If the file ends in .bin, don't add it. If it doesn't, add it, and open the file by that same name. Write a disassembler. Unfortunately, you
The first 32 bit value written to the file is: DABE.
It's often the case that a file has some sort of binary "signature" that indicates what kind of file it is. That way, when you're loading the file, you can determine if it's a legitimate file. While one could certainly write a bogus file that begins with DABE, the odds are pretty low that it would happen by accident.
I'd like to say that DABE stands for Decimal And Binary Encoding, or something officious-sounding. In reality, I chose it for several reasons. First, it can be written in hex. Second, it isn't as morbid-sounding as "DEAD BEEF", which also can be written in hex. Third, it's the name of a former 311 student and undergraduate staffer (from the mid 90s). Yes, his name was really "Dabe" (or at least, his nickname was).
After this initial part, you will store the data part.
For each label, do the following:
The size of the array should be stored in a 32 bit quantity, again, in big endian format.
This is actually somewhat challenging. Here's what you should do first.
Note: || means concatentation
Note: 016 means 16 zeroes.
Note: PC refers to the program counter
Note:
| Command | Explanation |
| add $rd, $rs, $rt |
|
| addi $rd, $rs, immed |
|
| sub $rd, $rs, $rt |
|
| and $rd, $rs, $rt |
|
| andi $rd, $rs, immed |
|
| or $rd, $rs, $rt |
|
| ori $rd, $rs, immed |
|
| xor $rd, $rs, $rt |
|
| xori $rd, $rs, immed |
|
| beq $rd, $rs, LABEL |
|
| bne $rd, $rs, LABEL |
|
| slt $rd, $rs, $rt |
|
| slti $rd, $rs, immed |
|
| jr $rd |
|
| j LABEL |
|
| jal LABEL |
|
| lw $rt, offset($rs) |
|
| lbu $rd, offset($rs) |
|
| sw $rt, offset($rs) |
|
| sb $rt, offset($rs) |
|
| lui $rt, immed |
|
| bgtz $rs, LABEL |
|
| bgez $rd, LABEL |
|
| bltz $rd, LABEL |
|
| blez $rd, LABEL |
|
| sll $rd, $rt, shift_amt |
|
| srl $rd, $rt, shift_amt |
|
Header: DABE
Address: 0x0000 2000
Type: 0x43
Size: 0x0000 0004
Data: 0x23 0x24 0x25 0x00
Address: 0x0000 2000
Type: 0x43
Size: 0x0000 0008
Data: 0x23 0x24 0x25 0x00
0x23 0x24 0x25 0x00
Number of Instructions: 0x0000 004A
Initial Addresss: 0x0000 0800
Instruction 0: 00 FF 00 FB
Instruction 1: 00 FF 23 CD
Instruction 2: 00 FF 23 CD
Print the header, then for each label, print its address in hex
(put a space between every four hex digits), the type using 2 hex
digits, the size in hex, the data (if it's byte/byte array/string,
list the quantities in hex format, with two hex digits. If it's a
word/word array, use 8 hex digits in a row.).
Put up to 8 values on each line, and continue on subsequent lines (without the "Data: " in front). Place a blank line between the "labels".
int fd ; // fd is called a file descriptor
ssize_t w1, w2 ;
char header1[ 512 ], header2[ 1024 ] ;
// Opens a file to be written, but only if file does not already exist.
if ( ( fd = open( "newfile", O_WRONLY|O_CREAT|O_EXCL, 0644 ) ) == -1 )
{
cout << "Error opening file" << endl ;
return -1 ;
}
w1 = write( fd, header1, 512 ) ;
w2 = write( fd, header1, 1024 ) ;
// close the file
close( fd ) ;
The write function takes a file descriptor of an opened
file, a pointer to some array (any type) or even just a plain
structure or variable, and the number of bytes that will be
written. The function returns an int-like value telling you
how many bytes were actually written.
To open a file for reading (in C),
int fd ; // fd is called a file descriptor
ssize_t n1, n2 ;
char buf[ 512 ], buf2[ 1024 ] ;
// Opens a file for read only
if ( ( fd = open( "oldfile", O_RDONLY ) ) == -1 )
{
cout << "Error opening file" << endl ;
return -1 ;
}
n1 = read( fd, buf1, 512 ) ;
n2 = read( fd, buf2, 1024 ) ;
// close the file
close( fd ) ;
Nelson Padua-Perez offers the C++ solution.
#include <iostream.h>
#include <stdlib.h>
#include <fstream.h>
struct Person
{
int id;
float salary;
};
// write takes a char *, and the number of bytes
void create_file(char *filename)
{
int x;
Person p;
ofstream out(filename, ios::out);
if (!out)
{
cerr << "File opening failed!" << endl;
exit(1);
}
for (x = 1; x <= 5; x++)
{
p.id = x;
p.salary = x * 100;
out.write(reinterpret_cast<const char *>(&p), sizeof(Person));
}
}
// read takes a char * pointer, and the number of bytes.
// Notice you can store into any object---endian-ness is an
// issue, however. If the file stores in big-endian, and the machine
// is little-endian, the number will be read in the wrong order.
// There's no information in the file to determine endian-ness.
void read_file(char *filename)
{
int x;
Person p;
ifstream in(filename, ios::in);
if (!in)
{
cerr << "File opening failed!" << endl;
exit(1);
}
for (x = 1; x <= 5; x++)
{
in.read(reinterpret_cast<char *>(&p), sizeof(Person));
cout << "ID: " << p.id << " , SALARY " << p.salary << endl;
}
}
void read_entry(int id, char *filename)
{
Person p;
ifstream in(filename, ios::in);
in.seekg((id - 1) * sizeof(Person));
in.read(reinterpret_cast<char *>(&p), sizeof(Person));
cout << "SID: " << p.id << " , SSALARY " << p.salary << endl;
}
void write_entry(int id, float salary, char *filename)
{
Person p;
ofstream out(filename, ios::out);
p.id = id;
p.salary = salary;
out.seekp((id - 1) * sizeof(Person));
out.write(reinterpret_cast<const char *>(&p), sizeof(Person));
}
int main()
{
create_file("data");
read_file("data"); // sequential reading
cout << "READING ENTRY" << endl;
read_entry(2, "data");
cout << "RANDOM WRITING" << endl;
write_entry(2, 1345, "data");
read_entry(2, "data");
return 0;
}
OUTPUT
% a.out
ID: 1 , SALARY 100
ID: 2 , SALARY 200
ID: 3 , SALARY 300
ID: 4 , SALARY 400
ID: 5 , SALARY 500
READING ENTRY
SID: 2 , SSALARY 200
RANDOM WRITING
SID: 2 , SSALARY 1345
%
|
See the class syllabus for policies concerning email Last Modified: Wed Jul 10 17:29:43 EDT 2002 |
|
|
|
|
|