Homework 1 Solutions

22C:116, Fall 1997

Douglas W. Jones

  1. What is your E-mail address? Solutions to this problem varied wildly, as you might hope!

  2. The Problem: Write a definition of the declaration for the type jmp_buf and write C (or Pascal or Ada or ...) code for longjup() and setjmp().
    	typedef long int jmp_buf[JMP_BUF_SIZE];
    
    The type jmp_buf ought to be a structure or record type, but in C, declaring it as an array allows instances to be statically instantiated while at the same time allowing objects of type jmp_buf to be implicitly passed by reference instead of by value, as would happen for any other standard type in C. This is an awful feature of the C language, we use it here to conform with the standard definition of jmp_buf. Therefore, fields in what ought to be a record will be given by constant offsets into the array:
    	#define JMP_BUF_RA 0  -- the return address
    	#define JMP_BUF_FP 1  -- the saved frame pointer
    	#define JMP_BUF_SIZE 2
    
    The above description is absolutely minimal! With this, we can write the following code:
    	int setjmp( jmp_buf b )
    	{
    	    long int * h;   -- a handle on the local variables;
    	    h = &h + RA_OFFSET; -- h points to the return address;
    	    b[JMP_BUF_RA] = *h;
    	    h = &h + FP_OFFSET; -- h points to the saved frame pointer;
    	    b[JMP_BUF_FP] = *h;
    	    return 0;
    	}
    
    	int longjmp( jmp_buf b, int v )
    	{
    	    long int * h;   -- a handle on the local variables;
    	    h = &h + RA_OFFSET; -- h points to the return address;
    	    *h = b[JMP_BUF_RA];
    	    h = &h + FP_OFFSET; -- h points to the saved frame pointer;
    	    *h = b[JMP_BUF_FP];
    	    return v;
    	}
    
    This version will only work if nothing in registers needs to be saved between setjmp and longjmp. Thus, if setjmp is called as a statement, it should work, but if it is called from within an expression where the results of evaluating other terms of the expression were saved in registers, it will not work because these values will be lost.

  3. The setjmp routine stores a context, and the longjmp routine transfers control to that context. Thus, longjmp is a context switching operation. The saved context is not complete (only some key pieces are saved), so it cannot be used to switch between arbitrary contexts, but the saved context is sufficient to allow longjmp to be used for exception handling -- its intended purpose.

  4. What is an interrupt? An interrupt is a control transfer that is forced by an event outside of the CPU. The routine to which control is transferred on interrupt is called the interrupt service routine. When an interrupt occurs, sufficient context information is saved that it is possible for the interrupt service routine to transfer control back to the interrupted program.