You are on page 1of 5

Subroutines Structured programming relies on subroutines.

Restricting our attention to C, we could write a subroutine that accepts three numerical arguments and returns their sum. This subroutine can then be used (or called) from many different places in our program. That is we could for example write the following in C: int add (int a, int b, int c) ! return a " b "c# $ int sum % &# main () ! sum "% add (', (, )# sum "% '&# sum "% add ('&, (&, &)# $ )or C subroutines to wor* as intended we need the following functionality: '. +e should be able to call a subroutine from anywhere in our program. ,y -call. we mean being able to change control flow so that the routine is executed. (. +e should be able to pass parameters that may ta*e different /alues across different calls. . 0 subroutine must be able to return a /alue. 1. 0 subroutine must be able to change control flow so that execution continues immediately after the point where it was called. Since a subroutine can be called from many different places this suggests that the routine should be able to differentiate between them and -return. to the right spot depending on where it was called from. +e can see these re2uirements at wor* in our example:

+e can see that the add subroutine is called from two different places. The place a routine is called from is also referred to as a call site. The three parameters that add accepts ta*e different /alues at each call site ((',(, ) and ('&,(&, &)). 0dd -returns. a /alue which is the sum of its three arguments. So, e/ery time add is called, it calculates a result and that result is returned as the subroutine3s /alue. This /alue can then be used in an expression (e.g., in add ('&,(&, &) e/aluates to 4&). The first time add is called we expect execution to resume immediately after the statement that called it. So, once add (',(, ) returns execution will resume by adding the return /alue to sum. Then, the -sum "% '&. statement will get executed. The second time add is called execution resumes immediately after the particular call. 5et3s re/iew the way control flows in time with subroutines with aid of the add example:

This diagram also shows a call site, the caller and the callee. The call site is the place a subroutine is called. The caller is the subroutine that is ma*ing the call. The callee is the subroutine that is called. +e can now loo* at the list of re2uired functionalities and since we are interested in how to implement subroutines in assembly we can add concerns6re2uirements that related to machine le/el constructs. Thus we need to pro/ide answers for the following 2uestions: '. (. . 1. 7ow does the subroutine returns immediately after the call site8 +here and how does it return a /alue8 +here and how are we passing arguments to a subroutine8 +here and how are we allocating storage for any local /ariables (i.e., /ariable that belong to the subroutine) 9. +hat happens to register /alues once a subroutine is called. :o we re2uire that the subroutine preser/es their /alues or is it ;< to o/erwrite some registers. +e will address each of these issues in turn. )or most machines there is a set of rules that all /alid subroutines must follow. This set of rules is called the calling convention. This set of rules is not the only /iable option for implementing subroutines. 7owe/er, at some point someone decided on a particular solution. =f we want a subroutine to interoperate correctly with other subroutines (possibly written by others) we ha/e to follow these set of rules. This way someone else could also use our subroutines. +e will be describing the calling con/ention used
3

by gcc for the 4>* family of processors. There are other con/entions in use in 4>*. 0t any gi/en point of time one of them can be in use, or special code must be de/ised to translate from one form to the other (and we do not want that). There are a few different options for pro/iding the aforementioned functionality. +e will present the solution used in 4>* and once this is understood we will discuss some of the other options. <ey to supporting subroutines in 4>* is the use of a stack. This stac* is used to pro/ide the functionality explained in points ' through 9 abo/e. +e first explain how a stac* can be implemented in 4>* machine code and then explain how the stac* is used to support subroutines. STACK: 5et3s re/iew what stac* is. Stac* is a last?in first?out (5=);) 2ueue. =n more detail, the stac* is a data structure for which three operations are defined:
'. @ush /alue (. @op . Top (distance)

The first operation adds a new element onto the stac*. The order in which elements are added onto the stac* is important. =nternally, the elements are placed in a 2ueue following exactly the order in which they were inserted. @ush ta*es a single argument which is the /alue we will insert onto the stac*. 0fter a push, the number of stac* elements increases by one. The pop operation remo/es the most recently inserted element within the stac*. 0fter a pop, the number of items in the stac* is reduced by one. =f the stac* is empty then pop is not a /alid operation. Top returns the /alue of a stac* element without remo/ing it from the stac*. Top accepts a single argument which specifies the relati/e to the most recently inserted element of the element we are interested in. So, top(&) returns the /alue of the most recently inserted element (this is also called the top of the stack , which corresponds to /iewing the stac* as a /ertical 2ueue with elements being placed on top of each other). Top( ) returns the /alue of the 1 th element in the stac* (as measured starting from the top). )or example, assuming that initially the stac* is empty here3s an example of how the stac* operates:
1. 2. 3. 4. 5. @ush ( ) @ush 1 (1, ) , where 1 is the top element @ush '& ('&, 1, ) Top(() returns Top(') returns 1
4

6. @op returns '& and then the stac* becomes (1, )

You might also like