OperatingSystem代写:CS281DevelopmentofNonlocalJumpFunctions


代写OS中Jump类方法中的setjmp()和longjmp(),这两个函数一般用于try-catch块的异常处理。

Overview

In this project, you will write the code of two C functions called setjmp()
and longjmp() which allow a program to transfer control directly from one
function to another without returning to the function that called them. These
two functions are available in the standard
C library but here you will write your own version.

Introduction

Note: The following description of the setjmp() and longjmp() behavior is
taken from
Section 8.6, Nonlocal Jumps, of the textbook “Computer systems : a
programmer’s perspective” by Bryant and O’Hallaron, 2nd edition (which we use
in CS 283).
C provides a form of user-level exceptional control flow, called a nonlocal
jump, that transfers control directly from one function to another currently
executing function without having to go through the normal call-and-return
sequence. Nonlocal jumps are provided by the setjmp and longjmp functions.
When called directly, the setjmp function saves the current calling
environment in the env buffer, for later use by longjmp, and returns a 0. The
calling environment includes the program counter, stack pointer, and general
purpose registers.
The longjmp function restores the calling environment from the env buffer and
then triggers a return from the most recent setjmp call that initialized env.
The setjmp then returns with the nonzero return value retval.
Notice that

  1. the setjmp function is called once, but returns multiple times:
    * a. once when the setjmp is first called and the calling environment is stored in the env buffer, and
    * b. once for each corresponding longjmp call
  2. the longjmp function is called once, but never returns
    An important application of nonlocal jumps is to permit an immediate return
    from a deeply nested function call, usually as a result of detecting some
    error condition. If an error condition is detected deep in a nested function
    call, we can use a nonlocal jump to return directly to a common localized
    error handler instead of laboriously unwinding the call stack.
    Figure 8.39 shows an example of how this might work. The main routine first
    calls setjmp to save the current calling environment, and then calls function
    foo, which in turn calls function bar. If foo or bar encounter an error, they
    return immediately from the setjmp via a longjmp call. The nonzero return
    value of the setjmp indicates the error type, which can then be decoded and
    handled in one place in the code.
    // This is Figure 8.39, Nonlocal jump example.
    // This example shows the framework for using nonlocal jumps
    // to recover from error conditions in deeply nested
    // functions without having to unwind the entire stack.
    // The code can be found in code/ecf/setjmp.c
    jmp_buf buf;
    int error1 = 0;
    int error2 = 1;
    void foo(void), bar(void);
    int main()
    {
    int rc;
    rc = setjmp(buf);
    if (rc == 0) foo();
    else if (rc == 1)
    printf(“Detected an error1 condition in foo\n”);
    else if (rc == 2)
    printf(“Detected an error2 condition in foo\n”);
    else
    printf(“Unknown error condition in foo\n”);
    exit(0);
    }
    /* Deeply nested function foo */
    void foo(void)
    {
    if (error1)
    longjmp(buf, 1);
    bar();
    }
    void bar(void)
    {
    if (error2)
    longjmp(buf, 2);
    }
    —|—

What to Do

Write the code for the two functions setjmp() and longjmp(). The code will
provide smaller functionality than the C library version and will simply work
correctly in the program shown below.
The only requirement is that when main () calls fun1() and fun1() calls
fun2(), if fun2() calls longjmp() - as it does in the example below - then
fun2() does not return to fun1() but instead setjmp() returns to main() with
return value equal to 1.
Start working on the project immediately after completing G2, the Programming
Assignment 2, which asks you to analyze the use of the stack in C programs.
The C compiler includes a call to __main, so we need to supply an empty
function
__main() to stop the SPIM simulator from complaining about an unresolved
symbol. The call to dummy(), another empty function, is necessary to force the
compiler to treat the calling function as a non-leaf function and produce all
the instructions that create a full frame in the stack. The code of the other
functions should be self-explanatory, except for print_hex () and print_str
(). Use these two functions as tools to print numbers and strings on the SPIM
simulator. Students who want to understand the workings of these two functions
should contact me for additional documentation.
What To Hand In

  • A text file with all C code including the two functions setjmp() and longjmp().
  • Screenshots of the SPIM simulator windows demonstrating that your program is working correctly.

文章作者: SafePoker
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 SafePoker !
  目录