Assignment 4, due Sep 19Solutions
Part of
the homework for CS:2630, Fall 2019
|
Assignment: The backspace, tab, vertical tab, linefeed and carriage return characters are the most important format effectors among the ASCII control characters. What do they do when you output them to the terminal window under C? What do they do when you output them from a Hawk program? Give your answer as a short sentence for each of these telling what it does and if the behavior is different or the same in the Hawk and C environments. (1.0 points, 0.2 per character)
Suggestion: You can design a single string that replaces "Hello world" and allows you to see the effect of each of these with a single experiment. You do not need to show your work, but if you show us your test strings for C and the Hawk environments, we can diagnose your errors.
Using this test string for C "BS\bBS HT\tHT VT\vVT LF\nLF CR\rCR\n" I got this output:
BBS HT HT VT VT LF CR CR
Translating the string to SMAL Hawk format is a bit ugly because you have to change, for example, "BS\bBS" to "BS",BS,"BS", but in the end, you get exactly the same output, so the following conclusion can be drawn for both programming environments:
000000: 000230F0 000004: 30F00200 000008: FA00FFFA
A Problem: Give equivalent Hawk code, with labels such as A, B and C used instead of numeric memory addresses. First, try it by hand, then use the emulator to check your work, and figure out what your errors were. (0.6 points, 0.1 point per instruction or operand error)
A: JUMP C B: BR D C: JUMP B D: BR A
The above is one of many best answers. At the cost of a small penalty, JUMP X can be rewritten JSR R0,X. These assemble to the same machine code, but using JSR implies an expected return, and there is none here. This little bit of code has both forward and backward versions of each instruction.
#include <stdio.h> #include <stdlib.h> #include <stdint.h> int main() { int i; for (i = 0; i < 100; i++) { void * p = malloc(i); printf( "%lX\n", (intptr_t)p ); } return 0; }
This program just prints out the addresses of 100 blocks of memory. The %lX in the format string asks it to print a long integer in hexadecimal, and the (intptr_t) cast on the pointer forces the pointer to be passed to printf as an integer, using an integer representation large enough to hold one pointer.
a) When you call malloc on the divisional Linux machines, what alignment guarantee does it give you about the pointer it returns? That is, does it return an arbitrary address, an address divisible by 2, divisible by 4, or what? (0.7 points)
All addresses returned by malloc are divisible by 16. That is, the hexadecimal value ends in 0.
b) When you call MALLOC on the Hawk, what alignment guarantee does it give you about the pointer it returns? (0.7 points)
All addresses returned by MALLOC are divisible by 4. That is, the hexadecimal value ends in 0, 4, 8 or C.
Suggestion: Instead of printing out 100 addresses and then trying to find a pattern, consider oring all of the addresses into a single value, then look at how many zero bits are on the bottom of the result after 100 allocations of various sizes of blocks. In Python, Java, C and C++, the a|b operator will or two values of any integer type; on the Hawk, the OR machine instruction does this for any two 32-bit registers.
If you use this suggestion, you can show your work by showing the value you got and your interpretation of that value.
Here is a little C program that illustrates the relevant logic:
#include#include #include int main() { int i; intptr_t acc = 0; for (i = 0; i < 100; i++) { void * p = malloc(i); acc = acc | (intptr_t)p; } printf( "%lX\n", acc ); return 0; }
And here is the output of a sequence of experiments with the above program:
[dwjones@fastx07 ~]$ a.out 13D1FF0 [dwjones@fastx07 ~]$ a.out 1A73FF0 [dwjones@fastx07 ~]$ a.out 1B9DFF0 [dwjones@fastx07 ~]$ a.out 4D1FF0 [dwjones@fastx07 ~]$ a.out 1107FF0
From the above, you can easily see that the malloc routine must have some degree of nondeterminism. Running the same program many times in a row, it always seems to get different addresses. The only pattern is that the addresses always end in 0. (Running the equivalent program on the Hawk, you'll find that MALLOC is deterministic. Every run will give the same result.)