// ISC machine code for an iterative factorial program // Using symbolic constants and labels (provided by the 'define' and // 'label' pseudo-opcodes), which will be translated by the ISC assembler. // repeats until end-of-file // accept an input number // call a subroutine that computes factorial of the number // output the number register return 0 // standard return address reg register result 1 // standard result register register arg1 2 // first argument register use jump_target // use to hold jump target addresses use zero // use to hold 0 origin 0 // start loading instructions at location 0 // set up standard register contents lim zero 0 // constant 0 lim jump_target io_setup // initialize io jsub jump_target return label loop lim jump_target input jsub jump_target return // get input value copy arg1 result lim jump_target fac jsub jump_target return // call fac routine copy arg1 result lim jump_target output jsub jump_target return // put output value lim jump_target loop junc jump_target // go back label fac // iterative factorial routine // initializes counter 'count' with argument value 'arg' // initializes an accumulator with value 1 // repeats as long as counter greater than 0 // multiply accumulator by counter // decrement counter // returns accumulated result in register 'result' lim result 1 // seed result with 1 lim jump_target test // set up for loop label test jlte return arg1 zero // return if count is 0 or less mul result result arg1 // multiply the counter by the accumulated value aim arg1 -1 // subtract 1 from the down counter junc jump_target // jump back to the test // i/o routines define input_word_loc -1 // fixed location for input word define input_status_loc -2 // fixed location for input status define output_word_loc -3 // fixed location for output word define output_status_loc -4 // fixed location for output status use input_word // register to hold input_word use input_status // register to hold input_status use output_word // register to hold output_word use output_status // register to hold input_status trace 0 // don't trace i/o label io_setup // setup registers for i/o lim input_word input_word_loc // memory-mapped input lim input_status input_status_loc // input status lim output_word output_word_loc // memory-mapped output lim output_status output_status_loc // input status junc return label input // input routine, returns result in register 'result' use temp // temporary register lim jump_target input // set up to loop back store input_status zero // wait for input ready load temp input_status // get input status jlt zero temp zero // quit (jump to 0) on end-of-file load result input_word // load from input word jeq jump_target temp zero // loop back if previous input not done junc return label output // output routine, outputs word in register 'arg1' load temp output_status // get output status in temp lim jump_target output // set up loop address jeq jump_target temp zero // wait for output ready store output_word arg1 // set up for output of result store output_status zero // request output junc return trace 1