; Generic Stack Assembly Language Simulation ; Written by Teresa Carrigan ; May 2004 globals [top interrupt step numOnStack console spindle myList myListInt myFile max-memloc explanation use-file? no-file save-no-file] breeds [ node stack memloc register memory-bus] memloc-own [ holds name address express ] node-own [ holds name ] register-own [ holds name ] stack-own [ name ] ; initialize the stack and global variables to setup ca set explanation "initializing stack" set spindle (-4 - screen-size-x ) set top (- screen-size-y * .4) set step 4 set numOnStack 0 set max-memloc 3 set interrupt false cct-stack 1 [ set shape "rectangle" setxy (spindle - 3) top set size 5.0 set name "nobody" ] cct-stack 1 [ set shape "rectangle" setxy spindle top set size 5.0 set name "nobody" ] cct-stack 1 [ set shape "rectangle" setxy (spindle + 3) top set size 5.0 set label "STACK" set name "stack" ] set top (top + step) setup-register setup-bus setup-file setup-memory update-show end ; no-file is a list of the lines of the program to be simulated to setup-no-file locals [ demo1 demo2 demo3 demo4 line done?] set use-file? false ifelse (member? "demo" choose-program-to-load ) [ set demo1 [ "push A" "push #5" "sub" "push B" "push #4" "add" "mul" "pop A" "halt"] set demo2 [ "push 1" "push 2" "add" "push #7" "push 3" "add" "mul" "pop 0" "halt"] set demo3 [ "push A" "push 5" "sub" "push B" "push 4" "add" "mul" "pop A" "halt"] set demo4 [ "push #4" "push A" "add" "push B" "halt" "push #3" "sub" "div" "pop A" ] run (word "set no-file " choose-program-to-load) ] [ ; must be TYPE set no-file [ ] set done? false while [ not done? ] [ set line user-input "Enter a line. Blank line to finish." ifelse (is-string? line) and ( line > "") [ set no-file lput line no-file ] [ set done? true ] ] ] set save-no-file no-file build-symbol-table set no-file save-no-file end ; output-file displays to the user the lines of the program currently loaded to output-file locals [ msg-string msg-list] set msg-string "" set msg-list save-no-file foreach msg-list [ set msg-string (word msg-string "\n" ? ) ] user-message msg-string end ; loads the program to be simulated to setup-file locals [line done? ] set use-file? true set no-file [] ifelse not (member? "BROWSE" choose-program-to-load ) [ setup-no-file ] [ set myFile user-choose-file ifelse file-exists? myFile [ file-close-all file-open myFile while [ (file-exists? myFile) and (not file-at-end?) ] [ set line upper! file-read-line set no-file lput line no-file set use-file? false ] file-close-all set save-no-file no-file build-symbol-table set no-file save-no-file ] [ set console "File not found" ] ] end ; each variable in the program must have a distinct memory location ; so we scan through the program looking for variables to build-symbol-table locals [n ] set explanation "Building symbol table" set myList [] set myListInt [] while [ not empty? no-file ] [ build-one-symbol ] set explanation "Symbols detected: " + myList set n 0 repeat max-memloc + 1 [ set myListInt lput (word " " n " ") myListInt set n (n + 1) ] end ; look at a single line of the program to see if there is a variable mentioned to build-one-symbol locals [ line ch num] if (not empty? no-file) [ set line upper! first no-file set no-file but-first no-file ifelse member? "PUSH" line or member? "POP" line [ set line remove "PUSH" line set line remove "POP" line set line remove " " line ifelse member? "#" line [ ; immediate mode operand is ignored ] [ifelse length line > 0 [set ch first line ifelse member? ch ["0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "0"] [ set num read-from-string line if num > max-memloc [ set max-memloc num ] ] [ if not member? line myList [set myList lput line myList ] ] ] [ ask stack with [ name = "stack"] [ set label "Push/Pop needs operand" set console "Push/Pop needs operand" set interrupt true set no-file [] set save-no-file [] halt ] ] ] ] [ ; not PUSH or POP if not check-command line [ ask stack with [ name = "stack"] [ set label "Unknown: " + line set console "Unknown: " + line set interrupt true set no-file [] set save-no-file [] halt ] ] ] ] end ; draw the data path and create the bus turtle to setup-bus locals [ horiz vert] ; start near the stack, on the left set vert (- screen-size-y * .4) set horiz spindle - 6 ; bus cct-memory-bus 1 [ set shape "circle" setxy horiz vert set size .5 set color red pd set heading 0 ; go up until you reach the program counter while [ ycor < (screen-size-y * .4 - 2.5) ] [ fd 1 ] rt 90 ; go right until you reach the memory locations while [ xcor < (screen-size-x * .4 - 2.75) ] [ fd 1 ] rt 90 ; go down until you are even with the bottom of the left side of the bus while [ ycor >= vert ] [ fd 1 ] pu setxy horiz vert hideturtle ] end ; create the three system registers at the top to setup-register locals [ horiz vert] set explanation "Program counter initialized" set vert (screen-size-y * .4) ; program counter cct-register 1 [ set shape "rectangle" set horiz ( 0 - screen-size-x * .3) setxy horiz vert set size 4.0 set name "PC" set holds 100 * random 40 set label "PC" ] ; extra room for instruction register cct-register 1 [ set shape "rectangle" set horiz -2 setxy horiz vert set size 4.0 set name " " set holds " " set label " " ] ; instruction register cct-register 1 [ set shape "rectangle" set horiz 1 setxy horiz vert set size 4.0 set name "IR" set holds "IR" set label "IR" ] ; condition code register cct-register 1 [ set shape "rectangle" set horiz 6 setxy horiz vert set size 4.0 set name "CC" set holds "CC" set label "CC" ] end ; add one memory location for each variable in the symbol table ; add extras if needed to setup-memory locals [ horiz vert n k] ; memory is on the right side of the screen, start near the top set horiz (screen-size-x * .4) set vert (screen-size-y * .4 - 4) set n 0 ; for each variable in symbol table repeat length myList [ cct-memloc 1 [ set shape "box" setxy horiz vert set size 4.0 set color green set name ( item n myList ) set express name set holds random random-memory set address n set n (n + 1) set label holds ] set vert (vert - 3) ] ; if reference is made in the program to a memory location ; by number, we must make certain that number is shown if max-memloc >= length myList [ set k (max-memloc - length myList + 1) repeat k [ cct-memloc 1 [ set shape "box" setxy horiz vert set size 4.0 set color green set name ( word " " n " ") set name (remove " " name) set express name set holds (random-memory - random (2 * random-memory)) set address n set n (n + 1) set label holds ] set vert (vert - 3) ] ] end ; update the labels on everything, depending on what the user wants to see to update-show ifelse what-to-show = "symbols" [ show-symbol] [ ifelse what-to-show = "address" [ show-address] [ ifelse what-to-show = "contents" [ show-holds ] [ show-express ] ] ] end to show-symbol ask memloc [ set label name ] ask node [ set label name ] ask register [ set label name ] end to show-address ask memloc [ set label address ] ask node [ set label name ] ask register [ set label name ] end to show-holds ask memloc [ set label holds ] ask node [ set label holds ] ask register [ set label holds ] end to show-express ask memloc [ set label express ] ask node [ set label name ] ask register [ set label holds ] end ; run all lines of the program, reading it from no-file to run-all while [ not empty? no-file and not interrupt ] [ run-line ] if interrupt [ ask stack with [ name = "stack"] [ set label "Execution interrupted"] set interrupt false ] end to abort ask stack with [ name = "stack"] [ set label "Interrupt flag set"] set interrupt true end ; animate the "fetch instruction" part of the cycle to go-fetch [ where line ] locals [vert horiz] ask stack with [ name = "stack"] [ set label "Fetch instruction"] ask memory-bus [ ; start at the program counter set vert (screen-size-y * .4 - 2) set horiz ( 0 - screen-size-x * .3) setxy horiz vert showturtle set color cyan set heading 90 set label-color blue ; bus now shows the address of instruction we need set label where set size 4.0 set shape "circle" ; follow the red path, toward the right and the memory locations while [ pcolor-of (patch-ahead 1) = red ] [ wait slow-me-down fd 1 ] rt 90 ; follow the red path, down to the bottom while [ pcolor-of (patch-ahead 1) = red ] [ wait slow-me-down fd 1 ] ; bus now shows the instruction it is fetching set label line wait slow-me-down rt 180 ; follow the red path up while [ pcolor-of (patch-ahead 1) = red ] [ fd 1 wait slow-me-down ] lt 90 ; follow the red path until we reach the instruction register while [ xcor > 1 ] [ fd 1 wait slow-me-down ] wait slow-me-down * 5 set color red set size .5 set label "" hideturtle ] update-show end ; returns the next line of the program, and increments the program counter to-report fetch locals [line where ] set explanation "Fetch next instruction" ifelse use-file? [ set line file-read-line] [ set line first no-file set no-file but-first no-file ] ask register with [ name = "PC"] [ set holds (holds + 1) ] report upper! line end to run-line locals [ line where] if (not empty? no-file) [ ask register with [ name = "PC" ] [ set where (holds) ] set line fetch go-fetch where line ask register with [ name = "IR" ] [ set holds line set label line ] ifelse member? "PUSH" line [ push (remove "PUSH" line) ] [ ifelse member? "POP" line [ pop (remove "POP" line) ] [ execute line true] ] ] end to execute [ command flag] locals [ vert horiz ] if check-command command [ set explanation "Executing " + command ask stack with [ name = "stack"] [ set label "Execute " + command] set vert (screen-size-y * .4 - 2) set horiz ( 1) ask memory-bus [ ; start at instruction register setxy horiz vert set label command set color cyan set heading -90 set label-color blue set size 4.0 set shape "circle" showturtle ; follow red path to left, then down to the stack while [ pcolor-of (patch-ahead 1) = red ] [ fd 1 wait slow-me-down ] lt 90 while [ pcolor-of (patch-ahead 1) = red ] [ fd 1 wait slow-me-down ] set label "" hideturtle ] ] if flag [ set flag check-command command] if flag [ run command] end to-report check-command [ cmd ] ifelse member? cmd [ "ADD" "SUB" "MUL" "DIV" "HALT" ] [ report true ] [ ask stack with [ name = "stack"] [ set label "Unknown: " + cmd] set console "Unknown: " + cmd halt report false ] end to fetch-operand [ pushItem ] locals [ pushValue vert horiz] ifelse member? "#" pushItem [ set explanation "Immediate mode push: " + (remove "#" pushItem) ] [ set explanation "Fetching " + pushItem + " from memory" ask stack with [ name = "stack"] [ set label "Fetch operand"] ] ; if operand is a symbol ifelse member? pushItem myList [ ask memloc with [ name = pushItem ] [ set vert ycor set horiz xcor set pushValue holds ] ] [ ; if operand is immediate mode number ifelse member? "#" pushItem [ set pushValue remove "#" pushItem set vert (screen-size-y * .4 - 2) set horiz ( 0 - screen-size-x * .3) ] [ ; operand must be direct memory location ask memloc with [ address = (read-from-string pushItem) ] [ set vert ycor set horiz xcor set pushValue holds ] ] ] ask memory-bus [ set label pushItem set color cyan set heading 90 set label-color blue set size 4.0 set shape "circle" showturtle ; vert and horiz give location of memory reference ; if horiz is to the right, then need to move to the right then down ; if it isn't, then it's immediate mode, so just go left if xcor < horiz - 3 [ while [ pcolor-of (patch-ahead 1) = red ] [ fd 1 wait slow-me-down ] rt 90 while [ ycor > vert ] [ fd 1 wait slow-me-down ] ] ; bus picks up operand set label pushValue set heading 0 ; bus takes operand to the stack while [ pcolor-of (patch-ahead 1) = red ] [ fd 1 wait slow-me-down ] lt 90 while [ pcolor-of (patch-ahead 1) = red ] [ fd 1 wait slow-me-down ] lt 90 set explanation "Executing push " + pushValue ask stack with [ name = "stack"] [ set label explanation] while [ pcolor-of (patch-ahead 1) = red ] [ fd 1 wait slow-me-down ] set label "" hideturtle ] end ; create a new node, place it on the top of the stack to push [ pushItem ] locals [ pushValue save-name save-label info] set pushItem (remove " " pushItem) if not any? stack [ setup ] set console "push " + pushItem fetch-operand pushItem cct-node 1 [ set shape "circle" set color red setxy spindle top set size 5.0 set info 0 ifelse member? pushItem myList [ ask memloc with [ name = pushItem ] [ set info holds set save-name pushItem set save-label pushItem ] ] [ ifelse member? "#" pushItem [ set pushItem (remove "#" pushItem) set info (read-from-string pushItem) set save-name pushItem set save-label pushItem ] [ ask memloc with [ address = (read-from-string pushItem) ] [ set info holds set save-name ( "mem[" + pushItem + "]") set save-label ( "mem[" + pushItem + "]") ] ] ] set holds info set-cc-reg holds set name save-name set label save-label ] set top (top + step) set numOnStack (numOnStack + 1) update-show end ; CC register is updated, depending on the results of the last operation to set-cc-reg [ contents ] locals [ flag ] if is-number? contents [ ifelse contents > 0 [ set flag "P +" ] [ ifelse contents = 0 [ set flag "Z 0" ] [ set flag "N -" ] ] ask register with [ name = "CC" ] [ set label flag set holds flag ] ] end ; Store "what" in memory location "dest" to store [ what dest ] locals [ vert horiz] set explanation "Popping " + what + " to " + dest ask stack with [ name = "stack"] [ set label explanation] ifelse member? dest myList [ ask memloc with [ name = dest] [ set vert ycor set horiz xcor ] ] [ ask memloc with [ address = (read-from-string dest) ] [ set vert ycor set horiz xcor ] ] ask memory-bus [ set label what set color cyan set heading 0 set label-color blue set size 4.0 set shape "circle" showturtle ; find the correct memory location while [ pcolor-of (patch-ahead 1) = red ] [ fd 1 wait slow-me-down ] rt 90 while [ pcolor-of (patch-ahead 1) = red ] [ fd 1 wait slow-me-down ] rt 90 while [ ycor > vert ] [ fd 1 wait slow-me-down ] set label "" hideturtle ] end ; remove the node at the top of the stack to pop [ dest ] locals [ save-name save-holds int-dest save-label] if not any? stack [ setup ] execute "pop" false ifelse any? node-at spindle (top - step) [ask node-at spindle (top - step) [ set console ("pop result = " + label ) set save-label label set save-name name set save-holds holds set-cc-reg holds die ] set dest (remove " " dest) store save-label dest ifelse member? dest myList [ ask memloc with [ name = dest ] [ set express save-name set holds save-holds ] ] [ ask memloc with [ address = (read-from-string dest) ] [ set express save-name set holds save-holds ] ] set top (top - step) ] [ set console "Stack is empty - can't pop!" ] set numOnStack (numOnStack - 1) update-show end ; Halt stops the program even if there are lines left to be run to halt set no-file [] end ; Remove the top two items from the stack, add them, and then push their sum onto the stack to add locals [ save-name save-holds save-label] if not any? stack [ setup ] ifelse any? node-at spindle (top - step - step) [ set console "add" ask node-at spindle (top - step) [ set save-name name set save-holds holds set save-label label die ] set top (top - step) ask node-at spindle (top - step) [ set label ( "(" + label + "+" + save-label + ")" ) set name ( "(" + name + "+" + save-name + ")" ) set holds ( holds + save-holds ) set-cc-reg holds ] ] [ set console "Two items needed to ADD" ] set numOnStack (numOnStack - 1) update-show end ; Remove the top two items from the stack, multiply them, and then push their product onto the stack. to mul locals [ save-name save-holds save-label] if not any? stack [ setup ] ifelse any? node-at spindle (top - step - step) [ set console "mul" ask node-at spindle (top - step) [ set save-name name set save-holds holds set save-label label die ] set top (top - step) ask node-at spindle (top - step) [ set label ( "(" + label + "*" + save-label + ")" ) set name ( "(" + name + "*" + save-name + ")" ) set holds ( holds * save-holds ) set-cc-reg holds ] ] [ set console "Two items needed to MUL" ] set numOnStack (numOnStack - 1) update-show end ; Remove the top two items from the stack, subtract them, and then push their difference onto the stack. to sub locals [ save-name save-holds save-label] if not any? stack [ setup ] ifelse any? node-at spindle (top - step - step) [ set console "sub" ask node-at spindle (top - step) [ set save-name name set save-holds holds set save-label label die ] set top (top - step) ask node-at spindle (top - step) [ set label ( "(" + label + "-" + save-label + ")" ) set name ( "(" + name + "-" + save-name + ")" ) set holds ( holds - save-holds ) set-cc-reg holds ] ] [ set console "Two items needed to SUB" ] set numOnStack (numOnStack - 1) update-show end ; Remove the top two items from the stack, divide them, and then push their quotient onto the stack. to div locals [ save-name save-holds save-label] if not any? stack [ setup ] ifelse any? node-at spindle (top - step - step) [ set console "div" ask node-at spindle (top - step) [ set save-name name set save-holds holds set save-label label die ] set top (top - step) ask node-at spindle (top - step) [ ifelse save-holds != 0 [ set label ( "(" + label + "/" + save-label + ")" ) set name ( "(" + name + "/" + save-name + ")" ) set holds int ( holds / save-holds ) ] [ set holds "ERROR" ask stack with [ name = "stack"] [ set label "Error - div by zero"] set console "Error - div by zero" halt ] set-cc-reg holds ] ] [ set console "Two items needed to DIV" ] set numOnStack (numOnStack - 1) update-show end ;----- these four procedures courtesy of James Steiner to-report string-from-list [ a-list ] ; collapses a list (of characters, preferably) ; into a string ifelse is-list? a-list and not empty? a-list [ report reduce [ (word ?1 ?2 ) ] a-list ] [ report "" ] end ;----- this procedure courtesy of James Steiner to-report list-from-string [ a-string ] ; expands a string into a list of single characters ; first make sure a-string contains string data ; use WORD to convert a-string to string data, set a-string (word "" a-string) ifelse is-string? a-string and a-string != "" [ report ( n-values (length a-string) [ item ? a-string] ) ] [ report [] ] end ;----- this procedure courtesy of James Steiner to-report upper! [ a-string ] locals [ upper-list ; contains the list of upper case characters lower-list ; contains the list of lower case characters ] set upper-list list-from-string "ABCDEFGHIJKLMNOPQRSTUVWXYZ" set lower-list list-from-string "abcdefghijklmnopqrstuvwxyz" ; you could certainly make upper-list and lower-list globals ; and set the values in setup, or add code here to setup the ; globals if they are not already setup, like this: ; if not is-list? upper-list [ set upper-list .... ] ; but I wanted to make these routines completely self-contained. ; report string-from-list ( map [ ifelse-value ( ( position ?1 lower-list ) = false ) [ ?1 ] [ ( item ( position ?1 lower-list ) upper-list ) ] ] ( list-from-string a-string ) ) end ;----- this procedure courtesy of James Steiner to-report lower! [ a-string ] locals [ upper-list ; contains the list of upper case characters lower-list ; contains the list of lower case characters ] set upper-list list-from-string "ABCDEFGHIJKLMNOPQRSTUVWXYZ" set lower-list list-from-string "abcdefghijklmnopqrstuvwxyz" ; you could certainly make upper-list and lower-list globals ; and set the values in setup, or add code here to setup the ; globals if they are not already setup, like this: ; if not is-list? upper-list [ set upper-list .... ] ; but I wanted to make these routines completely self-contained. ; report string-from-list ( map [ ifelse-value ( ( position ?1 upper-list ) = false ) [ ?1 ] [ ( item ( position ?1 upper-list ) lower-list ) ] ] ( list-from-string a-string ) ) End ;----------------------------------- ; *** NetLogo Model Copyright Notice *** ; ; Copyright 2004 by Teresa W. Carrigan. All rights reserved. ; James Steiner graciously provided the four procedures at the bottom, ; that allow easy conversion of a string to either upper or lower case. ; ; Permission to use, modify or redistribute this model is hereby granted, ; provided that both of the following requirements are followed: ; a) this copyright notice is included. ; b) this model will not be redistributed for profit without permission ; from Teresa W. Carrigan. ; Contact Teresa W. Carrigan for appropriate licenses for redistribution ; for profit. ; ; To refer to this model in academic publications, please use: ; Carrigan, T. (2004). Generic Stack Assembly Language Simulation model. ; Blackburn College, Carlinville IL. ; ; In other publications, please use: ; Copyright 2004 by Teresa W. Carrigan. All rights reserved. ; ; *** End of NetLogo Model Copyright Notice *** @#$#@#$#@ GRAPHICS-WINDOW 237 12 615 475 11 13 16.0 1 20 1 1 1 CC-WINDOW 16 433 229 528 Command Center BUTTON 10 62 115 95 NIL setup NIL 1 T OBSERVER T BUTTON 115 62 227 95 reset ca\nclear-output NIL 1 T OBSERVER T MONITOR 15 322 232 371 NIL console 0 1 BUTTON 12 134 114 167 step run-line NIL 1 T OBSERVER T CHOICE 14 199 229 244 what-to-show what-to-show "symbols" "contents" "address" "expressions" 3 BUTTON 14 244 231 277 change what shows update-show NIL 1 T OBSERVER T BUTTON 117 133 228 166 run run-all NIL 1 T OBSERVER T SLIDER 13 166 229 199 random-memory random-memory 0 100 25 1 1 NIL MONITOR 16 372 231 421 NIL explanation 0 1 CHOICE 9 15 226 60 choose-program-to-load choose-program-to-load "demo1" "demo2" "demo3" "demo4" "WRITE ONE" "BROWSE" 0 SLIDER 14 283 232 316 slow-me-down slow-me-down 0 0.5 0.05 0.0010 1 seconds BUTTON 10 97 116 130 display program output-file NIL 1 T OBSERVER T BUTTON 118 98 227 131 interrupt abort NIL 1 T OBSERVER T @#$#@#$#@ WHAT IS IT? ----------- This is a model of a generic zero-address computer, also known as a stack machine. The model animates the fetch-execute cycle as well as the stack. The user may choose to have the program show either the numeric contents of each memory location and item on the stack, or the algebraic expression. This allows students to test their stack machine programs to see if the programs correctly implement the assigned expression. When run from a website, the user may choose one of four sample programs, or may type in a program. When run from NetLogo, the user also may browse to select a program saved in a textfile. Please note that "BROWSE" does NOT work from an applet! HOW IT WORKS ------------ An assembly language program must be assembled, which constucts a symbol table. Memory locations mentioned in the program are shown on the right. The CPU contains a program counter, instruction register, CC register, stack, and a data path that connects the parts of the CPU with each other and to main memory (on the right). The fetch-execute cycle looks at the contents of the program counter to determine where to look for an instruction, then asks the bus to fetch the instruction in that location. The bus returns with the instruction, placing it in the instruction register. The program counter is incremented, so that it points to the next instruction, and the instruction in the instruction register is decoded to determine what to do with it. If the instruction mentions either a variable in the symbol table or a memory location, then the bus must fetch the operand. Finally, the instruction is executed. If the instruction is not a halt, then the cycle repeats. A generic stack machine assembly language has only six operations: Push, Pop, Add, Sub, Mul, and Div. Push adds an item to the top of the stack, then increments the stack pointer. Pop removes the item at the top of the stack. This model also allows a Halt operation, to better illustrate the fetch-execute cycle. HOW TO USE IT ------------- First, choose the program to load. This model comes with four sample programs, but you can choose to type in your own program or load a program that has been saved to a textfile. Please note that an applet can't load a textfile. The contents of all the memory locations will be randomized, based on the random-memory slider. For example, if the slider is set at 25, each memory location will contain a random number from -25 to +25. Changing this slider only effects the model when setup is pressed. Click setup to load the program and display the stack machine. You may now click either Step or Run to show the animation. Step animates the current line of the program loaded. You can press this repeatedly until the program halts or runs out of lines to be executed. Run animates the remainder of the program loaded. To run it again, you must press Setup. Interrupt sets an interrupt flag, and when the current fetch-execute cycle finishes, the cycle stops until either the step or run button is clicked. The next instruction will be the one that would have been processed if the interrupt had not occurred. Reset allows you to clear everything and start from scratch. Setup is supposed to do this for you. What-to-show lets the user decide what the labels of the turtles and patches will show. For example, if set at "contents" then the memory locations will show their contents, if set at "address" then the memory locations will show their addresses, and if set at "expression" then the stack items and memory locations will show algebraic expressions that have been used to calculate the values stored in them. When you make a change in What-to-show, press the "change what shows" button to activate the change. If you do not press the button, eventually the stack machine will notice and activate the change for you. The Slow-me-down slider allows the user to adjust the animation speed. At zero, the program runs so fast that you only see the final display. If you are testing a program, then .05 is a good setting. If you are studying the fetch-execute cycle or how a stack machine works, then .1 or higher would be better. The Console monitor gives messages about what is happening, including any error messages. The Explanation monitor gives the steps of the fetch-execute cycle as they are happening. THINGS TO NOTICE ---------------- Every time you Push an item, the stack gets one more item on top. For every time you Pop, Add, Sub, Mul, or Div, the stack loses one item. What happens when you try to Pop and the stack is empty? What happens when you have a single item on the stack, and you try to Add? When you press Sub, how does the stack determine which item is subtracted? When you push a number with a # in front of it, the number gets put on the stack without having to fetch an operand. When there is no # in front of the number, the bus fetches an operand that is the contents of that address, so the number pushed on the stack is probably completely different from what you get if there is #. Notice that the program counter is incremented as soon as the operand is fetched, before the instruction is executed. The CC register is updated after execution of each instruction. If the result is positive, then CC is changed to "P +"; if negative, then "N -" and if zero, then "Z 0". THINGS TO TRY ------------- Load one of the demo programs, then click Run. Watch the fetch-execute cycle working with each line of the program, and what the commands do to the stack. Run the same program twice, once with "What-to-show" set to expression, and again with it set to contents. Write down the values of each variable before running the program, and the values after running, then check against the expression stored; does the program do the calculations correctly? What happens when you divide and there is a remainder? What happens when the top of the stack is a zero, and the next command is div? What happens when there is a Halt command in the middle of a program? Run a program, and in the middle of it click interrupt. When does the CPU notice the interrupt? When does it stop to handle it? Write your own program, and test it using the model. EXTENDING THE MODEL ------------------- Add another operator to the possible commands, such as exponentiation, or sin. Show the memory locations of the lines of the program as well as the variables. Be sure to show the bus stopping at the correct line when it fetches an instruction. Modify push to limit the number of items that can be pushed on the stack (to prevent wrapping). Allow labels on lines, so that you can implement the various jump and branch opcodes. Add MAR and MBR registers, and separate the datapath into the internal bus, address bus, and data bus. Show the ALU, with the top two items of the stack going into it with the opcode being executed, and the result coming out then going on the top of the stack. NETLOGO FEATURES ---------------- In several places, the bus turtle uses while [ pcolor-of (patch-ahead 1) = red ] [ wait slow-me-down fd 1 ] to follow the datapath in a straight line, slowly enough that the animation can be seen. The setup-file procedure lets the user browse to find a saved textfile, opens it, and then reads the contents of the file into a list, with each line a separate list item. upper! converts a string to upper-case. The four demo programs had to be hard-coded as lists, because an applet won't allow them to be read from textfiles. RELATED MODELS -------------- Stack Machine CREDITS AND REFERENCES ---------------------- This model was written by Teresa W. Carrigan, 2004. James Steiner graciously provided the four procedures at the bottom, that allowed easy conversion of a string to either upper or lower case. Permission to use, modify or redistribute this model is hereby granted, provided that both of the following requirements are followed: a. this copyright notice is included. b. this model will not be redistributed for profit without permission from Teresa W. Carrigan. Contact Teresa W. Carrigan for appropriate licenses for redistribution for profit. To refer to this model in academic publications, please use: Carrigan, T. (2004). Generic Stack Assembly Language Simulation model. Blackburn College, Carlinville, IL. In other publications, please use: Copyright 2004 by Teresa W. Carrigan. All rights reserved. FOR MORE INFORMATION -------------------- For more information on Stack Machines, see one of these textbooks: [1.] Stallings, W. "Computer Organization and Architecture: Designing for Performance", Sixth Edition, Prentice Hall, pages 371-376. [2.] Tanenbaum, A. "Structured Computer Organization", Fourth Edition, Prentice Hall, pages 338-341. [3.] Null, L. and Lobur, J. "Essentials of Computer Architecture", First Edition, Jones & Bartlett. pages 204-207. For more information on the Fetch-Execute cycle, see one of these textbooks: [1.] Dale, N. and Lewis, J. "Computer Science Illuminated", Second Edition, Jones and Bartlett, pages 132-134. [2.] Null, L. and Lobur, J. "Essentials of Computer Architecture", First Edition, Jones and Bartlett, pages 28-29, 166-167. @#$#@#$#@ default true 0 Polygon -7566196 true true 150 5 40 250 150 205 260 250 arrow true 0 Polygon -7566196 true true 150 0 0 150 105 150 105 293 195 293 195 150 300 150 box true 0 Polygon -7566196 true true 45 255 255 255 255 45 45 45 circle false 0 Circle -7566196 true true 35 35 230 rectangle false 9 Rectangle -16776961 true false 0 46 299 257 thin-arrow true 0 Polygon -7566196 true true 150 0 0 150 120 150 120 293 180 293 180 150 300 150 @#$#@#$#@ NetLogo 2.0.1 @#$#@#$#@ @#$#@#$#@ @#$#@#$#@