Presentation on theme: "CSC 370 (Blum)1 Infix, Postfix and Stacks. CSC 370 (Blum)2 Ordering of opcodes and operands Another example of syntax is the ordering of opcode and operand(s)."— Presentation transcript:
CSC 370 (Blum)1 Infix, Postfix and Stacks
CSC 370 (Blum)2 Ordering of opcodes and operands Another example of syntax is the ordering of opcode and operand(s). Postfix: operand(s) then opcode –4 5 + –Works well with stacks Prefix: opcode then operand(s) –+ 4 5 Infix: operand opcode operand –4 + 5
CSC 370 (Blum)3 Precedence Precedence is the order in which operations occur when an expression contains more than one operation. Operations with higher precedence are performed before operators with lower precedence. –1 + 2 * – (multiplication has higher precedence) –7 - 4 (start on the left when operators have the same precedence) –3
CSC 370 (Blum)4 Infix to postfix To convert 1+2*3-4, put in parentheses even though they’re not strictly necessary for this expression –((1+(2*3))-4) Convert the innermost parentheses to postfix: 2*3 becomes 2 3 * –((1+(2 3 *))-4) –Once a group is in postfix order, it should be thought of as a unit (in particular as a single operand (data)), nothing should come in between any of the parts of the group Convert the next set of parentheses –((1 2 3 * +)-4)
CSC 370 (Blum)5 Infix to postfix The last step eliminated the innermost set of parentheses. Continue to convert from infix to postfix from the innermost to outermost parentheses. –(1 2 3 * + 4 -) Note there is one overall set of parentheses that can be thrown away. Also note that the order of the numbers has not changed.
CSC 370 (Blum)8 Postfix good for Hardware Postfix order is better suited for hardware since one must prepare the inputs (a.k.a. the data, a.k.a. the operands) before operating on them to get an output. Postfix is particularly well suited for architectures that use a stack to perform computations.
CSC 370 (Blum)9 The stack A stack is a data structure (which may be implemented in hardware or in software) that holds a sequence of data but limits the way in which data is accessed. A stack obeys the Last-In-First-Out (LIFO) protocol, the last item written (pushed) is the first item to be read (popped).
CSC 370 (Blum)10 Stack is pushed onto the stack 2 is popped off of the stack
CSC 370 (Blum)11 Stack Pointer: don’t move all the data just change the pointer X X X X X 1 X X X X 2 1 X X X X 2 1 X X X X 3 1 X X X The stack pointer is pointing to the next available location in the stack. When it’s pointing at the 2, the 2 is no longer on the stack.
CSC 370 (Blum)50 Infix to Postfix The approach taken for converting infix to postfix does not make for a good algorithm as it requires too many passes. –One passes over the expression introducing parentheses –One pass over the expression converting inner parentheses to postfix Fortunately there is a more efficient algorithm that requires only one pass through the expression.
CSC 370 (Blum)51 Infix to Postfix (Approach 2) This approach involves a stack used for operators. Proceed through the expression from left to right. Operands (numbers) are automatically added to the postfix expression we are generating (i.e. not put on the operator stack). What happens to a new operator depends on its precedence compared to that of the operator on the top of the stack.
CSC 370 (Blum)52 Infix to Postfix (Approach 2, Cont.) If the new operator has a higher precedence than the one on the top of the stack, it is pushed onto the stack. If the top of the stack is an open parenthesis, then the new operator is pushed onto the stack. If the operator has an equal or lower precedence than the one on the top of the stack, then the top of the stack is popped and added to the postfix expression until this is no longer the case. Then the current operator is pushed onto the stack.
CSC 370 (Blum)53 Infix to Postfix (Approach 2, Cont.) Left (opening parentheses) are always added to the stack. Right (closing parentheses) lead to everything up to and including the corresponding left parenthesis to be popped from the stack.
CSC 370 (Blum) (8 + 7) * * (4 + (3 * 2 + 1)) Operator Stack + ( * + Postfix Expression 987+6*+5432*1+ Comment: Pop the + and ( from the operator stack, add + to the postfix expression.
CSC 370 (Blum) (8 + 7) * * (4 + (3 * 2 + 1)) Operator Stack * + Postfix Expression 987+6*+5432*1++ Comment: Pop the + and ( from the operator stack, add + to the postfix expression.
CSC 370 (Blum) (8 + 7) * * (4 + (3 * 2 + 1)) Operator StackPostfix Expression 987+6*+5432*1++*+ Comment: Pop the * and then the + from the operator stack, add them the postfix expression.
CSC 370 (Blum)78 Another use for a stack We have seen a stack used for translating an infix expression into postfix. We have also seen a stack used to calculate a postfix expression. Another use of a stack is in subroutine and/or function calls.
CSC 370 (Blum)79 Input port 1Accumulator ALU Flags Input port 2 Prog. counter Mem.Add.Reg. Memory MDR Instr. Reg. Control C B TMP Output port 3 Output port 4 Display Keyboard encoder Bus
CSC 370 (Blum)80 Jump A processor generally assumes that the next statement to be executed is the next line of the code stored in memory. –Recall part of the fetch-execute cycle is to increment the program counter (PC). A jump or goto alters this usual plan. A new value is placed into the program counter.
CSC 370 (Blum)81 Conditional Jump A conditional jump will change the PC or leave it unchanged based on the state of one of the Flag registers. –The ALU can perform some comparison and place the result in a flag register, then the flag’s value could eventually be fed to the PC load control. So the PC is loaded (changed) or not based on the flag which came from the comparison. Conditional jumping gives the programmer ifs and loops.
CSC 370 (Blum)82 Calling a subroutine A subroutine call involves a jump. This “passes the control” to the subroutine. But a subroutine call differs from an ordinary jump in that one wants to return. –One reason for having subroutines is to reduce repeated code. The subroutine may be called from any number of locations, so the return address is not known until the program is running.
CSC 370 (Blum)83 Storing the PC Prior to executing the jump portion of a call, the PC holds the address of the line of code immediately following the call instruction. And this is where one wants to be upon returning from the subroutine. Thus we have to store the value of the program counter (somewhere) and then change the value of the PC (i.e. execute the jump)
CSC 370 (Blum)84 A subroutine can call another subroutine that can call another subroutine that …. There cannot be a simple register for storing the PC (return address) because a subroutine can call another subroutine requiring two stored values.
CSC 370 (Blum)85 Calling and Returning Calling: If Main calls RoutineA, we store the MainReturnAddress. Then if RoutineA calls RoutineB, we store RoutineAReturnAddress. Returning: RoutineB returns control to RoutineA so we first need the last return address stored (RoutineAReturnAddress). Then RoutineA returns the control to Main and we need MainReturnAddress. The last return address stored is the first one needed, this is the protocol of a stack. (LIFO)
CSC 370 (Blum)86 Call is to Push as Return is to Pop A subroutine call thus requires pushing the value of the PC onto a stack (and then changing the value of the PC). A return from a subroutine requires popping the return address from the stack (and then placing that value in the PC).
CSC 370 (Blum)87 More to it Subroutines and functions typically have arguments/parameters. This information is not known until run-time and must be passed to the subroutine/function. There must be memory locations (where are they?) to serve as the variables in the subroutine. And any passed information must be written to the appropriate location.
CSC 370 (Blum)88 By reference or by value The arguments of the subroutine call can be actual numbers –Y = sin(3) Or they could be variables associated with the caller. –Y = sin(x) There are two possible scenarios in the later case, by value and by reference.
CSC 370 (Blum)89 By value Passing a parameter by value means that the memory location associated with the subroutine will hold a value and that that value will be written into the memory location when the function is called. Any changes to that memory location have no effect of the memory location associated with the caller.
CSC 370 (Blum)90 By reference Passing a parameter by reference means that the memory location associated with the subroutine will hold the address of the variable in the caller. All actions on the variable in the subroutine are of the indirect variety (recall the different addressing modes). One goes to this location to find an address, then goes to that address, …. The caller and the called write values to the same memory location.
CSC 370 (Blum)91 Return value In addition to the passed parameters and any local variables required, a function also has a memory location associated with the value it will send back.
CSC 370 (Blum)92 Allowing more than one version of a subroutine to be active Where are all of these memory locations associated with subroutines? The answer can depend on the how many active versions of a given subroutine one allows. –A subroutine is considered active if it has started executing but hasn’t finished executing. That doesn’t imply it has control as it may have called some other routine before finishing.
CSC 370 (Blum)93 Activation Record All of the information required for an active subroutine –Return address –Passed parameters –Local variables –Return value constitute what is called the activation record.
CSC 370 (Blum)94 Multiprocessing and recursion One way in which a CPU may end up with more than one active versions of a subroutine is if it is multiprocessing, running more than one program at once (actually swapping between programs to give the illusion of running more than one.) But even a single process may require multiple active versions of a subroutine if the subroutine is recursive.
CSC 370 (Blum)95 One can’t know ahead of time If one allows for recursive subroutines, then one cannot know beforehand (at compile time) how much memory will be used by a subroutine since each active version requires separate memory. –Recursion programs can be very memory intensive. A common approach is that when a subroutine is called, an activation record is placed on the run- time stack. –For this reason, activation records are sometimes called stack frames.
CSC 370 (Blum)96 One more thing to remember Recall that the accumulator and other registers serve as a scratch pad area for the ALU. The ALU may be in the middle of some calculation when the subroutine is called and it may need to remember those temporary, scratch- pad values. –z = sin(x) + sqrt(y) –We cannot lose our result for sin(x) when we evaluate sqrt(y) Thus the stack frame may also include a copy of various register values.
CSC 370 (Blum)97 References Computer Architecture, Nichols Carter Modern Programming Languages, Adam Brooks Webber Computers Systems: Organization and Architecture, John Carpinelli s261/javaProgs/stack/Polish.html