Class: RubyLabs::MARSLab::MiniMARS

Inherits:
Object
  • Object
show all
Defined in:
lib/marslab.rb

Overview

MiniMARS

A miniature machine (MiniMARS) object is used to test a Redcode program. It is essentially a MARS VM connected to a “thumb drive” that contains the assembled code for a single program. By single-stepping through the program users can learn how the code works or debug a program they are developing.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(file, size = nil) ⇒ MiniMARS

Create a VM that has a memory with the assembled form of the Redcode program in file. has been loaded into location 0. The optional second argument defines the size of the memory (otherwise the memory is just big enough to hold the program).



672
673
674
675
676
677
678
679
680
681
682
# File 'lib/marslab.rb', line 672

def initialize(file, size = nil)
  w = Warrior.new(file)
  @mem = size ? Memory.new(size) : Memory.new(w.code.length)
  loc = 0
  w.code.each do |x|
    @mem.store(loc, x)
    loc = loc + 1
  end
  @pc = PC.new(w.name, w.symbols[:start])
  @state = :ready
end

Instance Attribute Details

#memObject (readonly)

Returns the value of attribute mem.



666
667
668
# File 'lib/marslab.rb', line 666

def mem
  @mem
end

#pcObject (readonly)

Returns the value of attribute pc.



666
667
668
# File 'lib/marslab.rb', line 666

def pc
  @pc
end

#stateObject (readonly)

Returns the value of attribute state.



666
667
668
# File 'lib/marslab.rb', line 666

def state
  @state
end

Instance Method Details

#dump(*args) ⇒ Object

Print the contents of the VM memory. If two arguments are passed they are used as the addresses of the first and last words to print.



740
741
742
743
744
745
746
747
748
749
# File 'lib/marslab.rb', line 740

def dump(*args)
  if args.empty?
    @mem.dump(0, @mem.array.length)
  else
    x = args[0]
    y = args[1] || x
    @mem.dump(x, y-x+1)
  end
  return nil
end

#inspectObject Also known as: to_s

Create a string with a short description of this VM.



686
687
688
# File 'lib/marslab.rb', line 686

def inspect
  return "#<MiniMARS mem = #{@mem.array.inspect} pc = #{@pc}>"
end

#resetObject

Reset the program counter to 0, so the program starts over. But the contents of memory are not restored, they are left as they were after the last instruction executed.



732
733
734
735
# File 'lib/marslab.rb', line 732

def reset
  @pc.reset
  puts "warning: memory may not be in initial state"
end

#run(nsteps = 1000) ⇒ Object

Execute instructions in the program loaded into this VM until it hits a HALT (DAT) instruction. The return value is the number of instructions executed. The optional argument is a maximum number of steps to execute; afer executing this number of instructions the method will return, whether or not the program halts.



717
718
719
720
721
722
723
724
725
726
# File 'lib/marslab.rb', line 717

def run(nsteps = 1000)
  count = 0
  loop do
    break if @state == :halt || nsteps <= 0
    self.step
    nsteps -= 1
    count += 1
  end
  return count 
end

#statusObject

Print a string that describes the program status (running or halted, current instruction address, …)



695
696
697
698
699
# File 'lib/marslab.rb', line 695

def status
  s = "Run: #{@state}"
  s += " PC: #{@pc}" unless @state == :halt
  puts s
end

#stepObject

Execute the next instruction in the program loaded into this VM. The return value is the Word object for the instruction just executed.



704
705
706
707
708
709
# File 'lib/marslab.rb', line 704

def step
  return "machine halted" if @state == :halt
  instr = @mem.fetch(@pc.next)
  @state = instr.execute(@pc, @mem)
  return instr
end