module Wilson
Wilson is a pure ruby x86 assembler. No, really. Worst Idea Evar.
Why “wilson”? I wanted to name it “metal”, but there is an existing project with that name… So I'm naming it after Wilson Bilkovich, who is about as metal as you can get (and it is easier to spell than “bilkovich”, even tho that sounds more metal).
Wilson is a port (and extension) of the smalltalk x86 assembler by Michael Lucas-Smith. I came across it when he presented it at Smalltalk SuperPowers at OOPSLA 2008.
Constants
- VERSION
Public Class Methods
commands()
click to toggle source
# File lib/wilson.rb, line 88 def self.commands self.default.commands end
default()
click to toggle source
# File lib/wilson.rb, line 80 def self.default @@default ||= self.new.parse end
default=(o)
click to toggle source
# File lib/wilson.rb, line 84 def self.default= o @@default = o end
new()
click to toggle source
# File lib/wilson.rb, line 96 def initialize self.commands = [] end
parse()
click to toggle source
# File lib/wilson.rb, line 92 def self.parse self.new.parse end
Public Instance Methods
add_command(command)
click to toggle source
# File lib/wilson.rb, line 140 def add_command command return self.add_conditional_commands(command) if command.opcode =~ /cc$/i self.commands << command self.expand_parameters command end
add_conditional_commands(prototype)
click to toggle source
# File lib/wilson.rb, line 118 def add_conditional_commands prototype prototype.opcode = prototype.opcode[0..-3] self.conditionals.each do |conditional, value| command = prototype.dup command.opcode += conditional command.opcodes.each_with_index do |op, index| command.opcodes[index] = ($1.hex+value).to_s(16) if op =~ /(.*)\+cc$/ end self.add_command command end end
conditionals()
click to toggle source
# File lib/wilson.rb, line 146 def conditionals @conditionals ||= { 'O' => 0, 'NO' => 1, 'B' => 2, 'C' => 2, 'NAE' => 2, 'AE' => 3, 'NB' => 3, 'NC' => 3, 'E' => 4, 'Z' => 4, 'NE' => 5, 'NZ' => 5, 'BE' => 6, 'NA' => 6, 'A' => 7, 'NBE' => 7, 'S' => 8, 'NS' => 9, 'P' => 10, 'PE' => 10, 'NP' => 11, 'PO' => 11, 'L' => 12, 'NGE' => 12, 'GE' => 13, 'NL' => 13, 'LE' => 14, 'NG' => 14, 'G' => 15, 'NLE' => 15, } end
expand_parameters(command)
click to toggle source
# File lib/wilson.rb, line 100 def expand_parameters command command.parameters.each_with_index do |parameter, index| if String === parameter && parameter =~ /^r\/m(\d+)/ then bits = $1.to_i newCommand = command.dup commands << newCommand case bits when 8, 16, 32 then command.parameters[index] = MemoryRegister.new bits newCommand.parameters[index] = Address.new false, bits when 64 then command.parameters[index] = MMXRegister.new bits newCommand.parameters[index] = Address.new false, bits end end end end
parse()
click to toggle source
# File lib/wilson.rb, line 174 def parse (self.class.nasm + self.class.nasm_fixes).each_line do |line| self.process_line line.strip.sub(/^# /, '') end self end
parse_command(line)
click to toggle source
# File lib/wilson.rb, line 157 def parse_command line if line =~ /^(\w+)\s+([^;]*)\s+;\s+([^\[]+)\s+\[([\w,]+)\]/ then name, params, ops, procs = $1, $2, $3, $4 command = Command.new command.opcode = name command.opcodes = ops.split command.processors = procs.split(/,/) command.initialize_parameters params.strip self.add_command command else raise "unparsed: #{line}" end end
process_line(line)
click to toggle source
# File lib/wilson.rb, line 133 def process_line line # TODO: remove return if line.empty? return unless line =~ /^[A-Z].+;.*\[/ self.parse_command line end