Assignment 11, due Nov 21Solutions
Part of
the homework for CS:2630, Fall 2019
|
Background: Consider the schematic diagram given here, containing 3 multiplexers, x, y and z where input c is connected to the control inputs of all the multiplexors input d is connected to x.0 (the zero data input of multiplexor x) and to y.1. The output x.out is connected to x.1 and z.1, and y.out is connected to y.0 and z.0. The output of the entire circuit, f is z.out.
a) First, consider just the behavior of the multiplexor y, enclosed in a grey box in the figure). This is some kind of flipflop. Give the values or behavior of c and d required to make y.out take a particular value, and the values or behavior required to make it remember that value, then name the type of flipflop discussed in the notes with similar behavior (and note any differences). (0.5 points)
When c = 1, y.out = d
When c = 0, y.out is held constant — that is, remembered.
Therefore, this is a regular type-D latch.
b) Now, consider the entire circuit. This is also some kind of flipflop (a bit more complex). Give the values or behavior of c and d required to make y.out take a particular value, and the values or behavior required to make it remember that value, then name the type of flipflop discussed in the notes with similar behavior (and note any differences). (0.5 points)
y.out = d when c = 1.
But when c = 1, f = x.out, which is remembered.
x.out = d when c = 0.
But when c = 0, f = y.out, which is remembered.
Therefore, this is an edge-triggered flipflop where f only changes when c changes from 0 to 1 or from 1 to 0. It is triggered on both the leading and trailing edges of the c input, which makes it different from any of the edge-triggered flipflops in the notes.
a) Give a SMAL data structure description for jmp_buf compatable with our standard Hawk calling sequence. (0.5 points)
; structure of a jump buffer JBRASV = 0 ; saved return address JBR2SV = 4 ; saved frame pointer JBR8SV = 8 ; saved R8 and up JBR9SV = 12 JBRASV = 16 JBRBSV = 20 ; -- these are saved because JBRCSV = 24 ; -- the Hawk calling conventions JBRDSV = 28 ; -- require R8-15 to survive JBRESV = 36 ; -- subroutine calls JBRFSV = 40 JBSIZE = 42
b) Give SMAL Hawk code for SETJMP that behaves like C's setjmp. (0.5 points)
SETJMP: ; expects R3 = jb, the address of a jump buffer ; returns R3 = null, except for return from LONGJMP STORES R1,R3 ; jb->rasv = return-address STORE R2,R3,JBR2SV ; jb->r2sv = frame-pointer STORE R8,R3,JBR8SV ; jb->r8sv = R8 STORE R9,R3,JBR9SV ; ... etc ... STORE RA,R3,JBRASV STORE RB,R3,JBRBSV STORE RC,R3,JBRCSV STORE RD,R3,JBRDSV STORE RE,R3,JBRESV STORE RF,R3,JBRFSV LIS R3,0 JUMPS R1 ; return NULL
c) Give SMAL Hawk code for LONGJMP that behaves like C's longjmp. (0.5 points)
LONGJMP:; expects R3 = jb, the address of a jump buffer ; R4 = ret, the return value ; does not return to the point of call ; returns R3 = ret, but returns to the point of call to SETJMP LOADS R1,R3 ; return-address = jb->rasv LOAD R2,R3,JBR2SV ; frame-pointer = jb->r2sv LOAD R8,R3,JBR8SV ; R8 = jb->r8sv LOAD R9,R3,JBR9SV ; ... etc ... LOAD RA,R3,JBRASV LOAD RB,R3,JBRBSV LOAD RC,R3,JBRCSV LOAD RD,R3,JBRDSV LOAD RE,R3,JBRESV LOAD RF,R3,JBRFSV MOVE R3,R4 JUMPS R1 ; return ret
# includetypedef struct node { struct node * left; struct node * right; int (*thing)(const char *); /* fixed to work with puts() */ char * value; } node; void doit( node * n ) { if (n != NULL) { doit( n->left ); (n->thing)( n->value ); doit( n->right ); } } node lson = { NULL, NULL, &puts, "left son's string" }; node rson = { NULL, NULL, &puts, "right son's string" }; node root = { &lson, &rson, &puts, "root's string" }; int main() { doit( &root ); return 0; }