Class: Wilson::Assembler
Overview
Assembler parses the NASM documentation and creates Command objects for it
Constant Summary collapse
- @@default =
nil
Instance Attribute Summary collapse
-
#commands ⇒ Object
Returns the value of attribute commands.
Class Method Summary collapse
- .commands ⇒ Object
- .default ⇒ Object
- .default=(o) ⇒ Object
- .nasm ⇒ Object
- .nasm_fixes ⇒ Object
- .parse ⇒ Object
Instance Method Summary collapse
- #add_command(command) ⇒ Object
- #add_conditional_commands(prototype) ⇒ Object
- #conditionals ⇒ Object
- #expand_parameters(command) ⇒ Object
-
#initialize ⇒ Assembler
constructor
A new instance of Assembler.
- #parse ⇒ Object
- #parse_command(line) ⇒ Object
-
#process_line(line) ⇒ Object
TODO: remove.
Constructor Details
#initialize ⇒ Assembler
Returns a new instance of Assembler.
97 98 99 |
# File 'lib/wilson.rb', line 97 def initialize self.commands = [] end |
Instance Attribute Details
#commands ⇒ Object
Returns the value of attribute commands.
41 42 43 |
# File 'lib/wilson.rb', line 41 def commands @commands end |
Class Method Details
.commands ⇒ Object
89 90 91 |
# File 'lib/wilson.rb', line 89 def self.commands self.default.commands end |
.default ⇒ Object
81 82 83 |
# File 'lib/wilson.rb', line 81 def self.default @@default ||= self.new.parse end |
.default=(o) ⇒ Object
85 86 87 |
# File 'lib/wilson.rb', line 85 def self.default= o @@default = o end |
.nasm ⇒ Object
75 76 77 |
# File 'lib/wilson.rb', line 75 def self.nasm File.read(__FILE__).split(/__END__/).last end |
.nasm_fixes ⇒ Object
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/wilson.rb', line 43 def self.nasm_fixes # TODO: extend parser to split /[,:]/ and remove some of these ' CALL imm,imm16 ; o16 9A iw iw [8086] CALL imm,imm32 ; o32 9A id iw [386] CALLFAR mem16 ; o16 FF /3 [8086] CALLFAR mem32 ; o32 FF /3 [386] Jcc imm ; 0F 80+cc rw/rd [386] JMP imm,imm16 ; o16 EA iw iw [8086] JMP imm,imm32 ; o32 EA id iw [386] JMP imm16 ; E9 rw/rd [8086] JMP imm32 ; E9 rw/rd [8086] JMP imm8 ; EB rb [8086] JMPFAR mem16 ; o16 FF /5 [8086] JMPFAR mem32 ; o32 FF /5 [386] FADDTO fpureg ; DC C0+r [8086,FPU] FDIVTO fpureg ; DC F8+r [8086,FPU] FDIVRTO fpureg ; DC F0+r [8086,FPU] FMULTO fpureg ; DC C8+r [8086,FPU] FSUBTO fpureg ; DC E8+r [8086,FPU] FSUBRTO fpureg ; DC E0+r [8086,FPU] CMP r/m16,imm8 ; o16 83 /7 ib [8086] CMP r/m32,imm8 ; o32 83 /7 ib [386] SAR r/m16,1 ; o16 D1 /7 [8086] SAR r/m32,1 ; o32 D1 /7 [386] ' end |
.parse ⇒ Object
93 94 95 |
# File 'lib/wilson.rb', line 93 def self.parse self.new.parse end |
Instance Method Details
#add_command(command) ⇒ Object
141 142 143 144 145 |
# File 'lib/wilson.rb', line 141 def add_command command return self.add_conditional_commands(command) if command.opcode =~ /cc$/i self.commands << command self. command end |
#add_conditional_commands(prototype) ⇒ Object
119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/wilson.rb', line 119 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 ⇒ Object
147 148 149 150 151 152 153 154 155 156 |
# File 'lib/wilson.rb', line 147 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) ⇒ Object
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'lib/wilson.rb', line 101 def 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 ⇒ Object
175 176 177 178 179 180 181 |
# File 'lib/wilson.rb', line 175 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) ⇒ Object
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 |
# File 'lib/wilson.rb', line 158 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) ⇒ Object
TODO: remove
134 135 136 137 138 139 |
# File 'lib/wilson.rb', line 134 def process_line line # TODO: remove return if line.empty? return unless line =~ /^[A-Z].+;.*\[/ self.parse_command line end |