Assignment 5: Raw Memory: Bits and Bytes
Assignment 5: Raw Memory: Bits and Bytes
Assignment 5: Raw Memory: Bits and Bytes
which says to compile the file binky.cc, link it, and name the resulting
executable binky.
To compile multiple files into one executable, you first compile each file separately:
that takes the two compiled object files and links them together into one
executable called word-games.
You can also add other flags for compiling after the gcc such as -Wall (to generate all
warnings), -g (to include debugging information, and -O (for optimization).
2
Try converting a few decimal numbers into binary form, do some binary arithmetic
with them (add, subtract, maybe even a multiply), and convert the result back to
decimal to verify you have it correct. This lets you know you are on top of the basic
workings and know how to do all that tedious carrying.
Write a test program to find out what happens when you overflow the range of a
variable, such as adding two shorts that are both very large. Is any error reported on
the overflow? How is the result related to what the desired answer would have been?
What happens when you do the same thing with unsigned shorts instead of signed?
Write a program that assigns values between different-sized integer types. What
happens when you go from a smaller-sized type to a larger? What about the other
direction? How is the result related to the original number? Does this match your
understanding of the binary representation?
In addition to the usual logical AND, OR, and NOT connectives, there are bitwise
versions of these operations available in C. The bitwise AND (expressed with single &)
compares its two operands bit-by-bit and reports which bits were 1 in both, 0 otherwise.
For example:
Doing a bitwise AND on 00001100 (12 in binary) and 00000101 (5 in binary) gives the
result 00000100, since the two patterns have only one bit in common.
There is a bitwise OR operator (single |) that works similarly to logical OR, but operates
at the bit level. There is also a bitwise exclusive OR (^) that reports which bits are on in
one operand, but not both. The bitwise NOT (~) is a unary operator that just inverts all
of the bits in its operand. Bit manipulations are used in a variety of situations (graphics,
robotics, cryptography, etc.) especially when you need to work with a form of packed
data.
How could you use bit operations to determine the remainder of a number when
divided by 4 (or any power of two for that matter?) How could use a bit approach to
determine if an integer would lose data when assigned to a short or a char?
How can you use bit operations to convert a number from negative to positive or vice
versa? (Refer back to the “two’s complement” representation for negative numbers
we showed in class and try to work through what the patterns are in terms of bits.)
One neat feature of the bitwise XOR operation is that it is completely invertible. If
you XOR a with b and then XOR the result with b again, you get back a (trace this out
for yourself). This makes this operation useful for encryption and decryption. How
3
could you construct a simple program that encrypts a file using XOR and a specified
“key”? What would happen if you run the program twice in a row using the same
key?
What implications does this have for using extended ASCII characters in a Web page
intended to be viewed by all? What about sending those characters in e-mail exchanged
between different computers? Does this exercise help explain any weird character
translation problems you may have run into in the past?
This type of x operation is also available at runtime using a typecast. For safety reasons,
most languages don't expose the typecast mechanism to the programmer and therefore
constrain type conversion to a limited set of operations that actually make sense. C, on
4
the other hand, allows the typecast to be freely used in (almost) all situations, allowing
the programmer immense control over interpretation of data, but also providing
opportunity for lots of errors. You can do a lot of very twisted and weird things with
typecasts, most of which you probably shouldn't even want to do. To show off your new
prowess as a master of data manipulation, here are a few pressing needs you can solve.
Try to construct a code snippet using a typecast that will:
Print out the contents of a 4-byte struct as though it were a 4-byte float.
Directly copy the first four characters of a string and assign them into an integer
variable.
Report whether the architecture is big or little endian. Recall big-endian means the
most significant byte of a multi-byte value is at the lowest address, vice versa for
little-endian.
R2 = Mem[SP]
R3 = R2 + 4
R4 = Mem[SP + 4]
Mem[R4] = R3
a) Assuming that SP holds the address of the last local variable (and others follow at
higher addresses), build a C snippet with variables of only pointer type (any type of
pointer okay) that will compile to the above sequence of machine instructions. The
code should not have any typecasts.
b) Construct another function with just one local variable involving only integer type
(array or structs of integers also okay) that compiles to the same sequence of
machine instructions. You can use typecasts if necessary.
5
1 2 3
struct list {
int data;
struct list *next;
};
Write a function that looks through the heap to see if a (1,2,3) list is present anywhere.
Assume that the function takes no inputs but returns true if the list is present and false
otherwise. You can assume that kHeapStart (a void *) and kHeapSize (an int) are global
constants defined for you. Your function should not dereference any invalid pointers.
Do not worry about alignment restrictions or rounding up allocations to some larger
value.
b) Now generate code for the puppetthing function. You needn’t draw the stack
frame out, but it can only help.
homestarrunner **puppetthing(homestarrunner *marshie,
homestarrunner& mrshmallow)
{
return (**puppetthing(&mrshmallow, *marshie)).strongbad;
}
6
class jedimaster {
public:
int luke(jedimaster *macewindu, jedimaster obiwan);
int& anakin(short *padme, jedimaster& leia);
private:
short council[4];
short *yoda;
};