7.7.函数抽象

7.7.Function: Abstraction

1.Function in VM language

  • The VM language features:

    • primitive operation(fixed): add, sub
    • abstract operation(extensible): mutiple

  When we want to call a function, we:

  • push the required argument onto the stack.
  • call the function. Then the result of function will replace the argument you push earlier.

  Take this simple funtion call sqrt(x-17+x*5) as example, it can be translated into:

1
2
3
4
5
6
7
8
push x
push 17
sub
push x
push 5
call Math.multiply
add
call Math.sqrt

2.Function definition

  Take the previous function as example:

1
2
3
4
5
6
7
8
9
10
// returns x"y
int mult(int x, int y) {
int sum = 0;
int n = 1;
while !(n>y) {
sum += x;
x ++;
}
return sum;
}

  As is discussed before, it's pseudo VM code is as below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function mult(x,y)
push 0
pop sum
push 1
pop n
label LOOP
push n
push y
gt
if-goto ENDLOOP
push sum
push x
add
pop sum
push n
push 1
add
pop n
goto LOOP
label ENDLOOP
push sum
return

  In fact, it can be translated into this VM code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function mult 2
push constant 0 //sum = 0
pop local 0
push constant 1 //n = 1
pop local 1
label LOOP
push local 1 //if clause
push argument 1
gt
if-goto ENDLOOP
push local 0 // sum += x
push argument 0
add
pop local 0
pop local 1 // n ++
push constant 1
add
pop local 1
goto LOOP
label ENDLOOP
push local 0 // return sum
return

  Let's discuss the implementation in detail:

  1. Function declaration:

    • Function: function declaration.
    • mult: the name of the function.
    • 2: use 2 local variables in the function.
  2. Function body:

    • branching.
    • the variable declared within the body should be stored in local.
    • the assignment of variables can be done through push constant and pop local.
  3. Return value

    • push the to-return value in the stack.
    • return statement at the end of program.

3.Function execution

  We can execute a function in a Main function:

1
2
3
4
5
6
7
function main 0
push constant 3
push constant 5
push constant 8
call mult 2
add
return

  • the 2 next to mult indicates that the funtion takes in 2 arguments.
  • the whole process can be described through these diagrams:

  for each function call during run-time, the implementation of the call command should :

  • Pass parameters from the calling function to the called function;

  • Determine the return address within the caller's code;

  • Save the caller's return address, stack and memory segments;

    • so that when we return to the main, we will be able to recreate the private world of main.
  • Jump to execute the called fiunction:

  And for each function return during run-time, the impletation has to:

  • Return to the caller the value computed by the called function;

    • The implementation knows that the topmost value on the stack must be the return value, so it returns the value.
  • Recycle the memory resources used by the called funetion;

  • Reinstate the caller's stack and memory segments;

  • Jump to the return address in the caller's code.