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.
170 171 172 |
# File 'lib/wilson.rb', line 170 def initialize self.commands = [] end |
Instance Attribute Details
#commands ⇒ Object
Returns the value of attribute commands.
119 120 121 |
# File 'lib/wilson.rb', line 119 def commands @commands end |
Class Method Details
.commands ⇒ Object
162 163 164 |
# File 'lib/wilson.rb', line 162 def self.commands self.default.commands end |
.default ⇒ Object
154 155 156 |
# File 'lib/wilson.rb', line 154 def self.default @@default ||= self.new.parse end |
.default=(o) ⇒ Object
158 159 160 |
# File 'lib/wilson.rb', line 158 def self.default= o @@default = o end |
.nasm ⇒ Object
148 149 150 |
# File 'lib/wilson.rb', line 148 def self.nasm File.read(__FILE__).split(/__END__/).last end |
.nasm_fixes ⇒ Object
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
# File 'lib/wilson.rb', line 121 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] ' end |
.parse ⇒ Object
166 167 168 |
# File 'lib/wilson.rb', line 166 def self.parse self.new.parse end |
Instance Method Details
#add_command(command) ⇒ Object
214 215 216 217 218 |
# File 'lib/wilson.rb', line 214 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
192 193 194 195 196 197 198 199 200 201 202 203 204 205 |
# File 'lib/wilson.rb', line 192 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
220 221 222 223 224 225 226 227 228 229 |
# File 'lib/wilson.rb', line 220 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
174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 |
# File 'lib/wilson.rb', line 174 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
248 249 250 251 252 253 |
# File 'lib/wilson.rb', line 248 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
231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 |
# File 'lib/wilson.rb', line 231 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
207 208 209 210 211 212 |
# File 'lib/wilson.rb', line 207 def process_line line # TODO: remove return if line.empty? return unless line =~ /^[A-Z].+;.*\[/ self.parse_command line end |