// ISC machine code for a recursive factorial program // 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 // register 0 will hold 0 use stack_pointer // stack pointer register 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 lim stack_pointer save_area_loc // initialize stack pointer aim stack_pointer -1 // always point to top of stack label loop lim jump_target input jsub jump_target return // get input value copy arg1 result // initialize 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 // recursive factorial routine // returns accumulated result in register 'result' lim result 1 // basis is 1 jlte return arg1 zero // return if arg is 0 or less aim stack_pointer +1 // increment stack pointer store stack_pointer return // save return address on stack aim stack_pointer +1 // increment stack pointer store stack_pointer arg1 // save argument on stack aim arg1 -1 // subtract 1 from argument jsub jump_target return // call recursively // result will be in result load arg1 stack_pointer // restore original arg aim stack_pointer -1 load return stack_pointer // restore original return address aim stack_pointer -1 mul result result arg1 // multiply the recursive result by original arg junc return // return to caller // 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 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 use temp // temporary register label input // input routine, returns result in register 'result' 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 label save_area_loc // first location in save area