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.
184 185 186 |
# File 'lib/wilson.rb', line 184 def initialize self.commands = [] end |
Instance Attribute Details
#commands ⇒ Object
Returns the value of attribute commands.
133 134 135 |
# File 'lib/wilson.rb', line 133 def commands @commands end |
Class Method Details
.commands ⇒ Object
176 177 178 |
# File 'lib/wilson.rb', line 176 def self.commands self.default.commands end |
.default ⇒ Object
168 169 170 |
# File 'lib/wilson.rb', line 168 def self.default @@default ||= self.new.parse end |
.default=(o) ⇒ Object
172 173 174 |
# File 'lib/wilson.rb', line 172 def self.default= o @@default = o end |
.nasm ⇒ Object
162 163 164 |
# File 'lib/wilson.rb', line 162 def self.nasm File.read(__FILE__).split(/__END__/).last end |
.nasm_fixes ⇒ Object
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
# File 'lib/wilson.rb', line 135 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
180 181 182 |
# File 'lib/wilson.rb', line 180 def self.parse self.new.parse end |
Instance Method Details
#add_command(command) ⇒ Object
228 229 230 231 232 |
# File 'lib/wilson.rb', line 228 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
206 207 208 209 210 211 212 213 214 215 216 217 218 219 |
# File 'lib/wilson.rb', line 206 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
234 235 236 237 238 239 240 241 242 243 |
# File 'lib/wilson.rb', line 234 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
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 |
# File 'lib/wilson.rb', line 188 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
262 263 264 265 266 267 |
# File 'lib/wilson.rb', line 262 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
245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 |
# File 'lib/wilson.rb', line 245 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
221 222 223 224 225 226 |
# File 'lib/wilson.rb', line 221 def process_line line # TODO: remove return if line.empty? return unless line =~ /^[A-Z].+;.*\[/ self.parse_command line end |