rename objects to value sin assembler

This commit is contained in:
Torsten Ruger 2014-04-22 22:24:22 +03:00
parent e23211602b
commit 1dedc41e39
8 changed files with 48 additions and 36 deletions

View File

@ -3,7 +3,7 @@ module Asm
# TODO actually find the closest somehow (DROPPED for now) # TODO actually find the closest somehow (DROPPED for now)
def self.closest_addrtable(as) def self.closest_addrtable(as)
as.objects.find do |obj| as.values.find do |obj|
obj.is_a?(Asm::Arm::AddrTableObject) obj.is_a?(Asm::Arm::AddrTableObject)
end || (raise Asm::AssemblyError.new('could not find addrtable to use', nil)) end || (raise Asm::AssemblyError.new('could not find addrtable to use', nil))
end end

View File

@ -13,10 +13,6 @@ module Asm
class ArmAssembler < Asm::Assembler class ArmAssembler < Asm::Assembler
def add_data(str)
add_object Asm::DataObject.new(str)
end
%w(r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 %w(r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12
r13 r14 r15 a1 a2 a3 a4 v1 v2 v3 v4 v5 v6 r13 r14 r15 a1 a2 a3 a4 v1 v2 v3 v4 v5 v6
rfp sl fp ip sp lr pc rfp sl fp ip sp lr pc
@ -36,6 +32,8 @@ module Asm
node.args << arg node.args << arg
elsif (arg.is_a?(Integer)) elsif (arg.is_a?(Integer))
node.args << Asm::NumLiteralNode.new(arg) node.args << Asm::NumLiteralNode.new(arg)
elsif (arg.is_a?(String))
node.args << add_string(arg)
elsif (arg.is_a?(Symbol)) elsif (arg.is_a?(Symbol))
node.args << Asm::LabelRefNode.new(arg.to_s) node.args << Asm::LabelRefNode.new(arg.to_s)
elsif (arg.is_a?(Asm::Arm::GeneratorLabel) or arg.is_a?(Asm::Arm::GeneratorExternLabel)) elsif (arg.is_a?(Asm::Arm::GeneratorLabel) or arg.is_a?(Asm::Arm::GeneratorExternLabel))
@ -45,7 +43,7 @@ module Asm
end end
} }
add_object Asm::Arm::Instruction.new(node) add_value Asm::Arm::Instruction.new(node)
end end
%w(adc add and bic eor orr rsb rsc sbc sub mov mvn cmn cmp teq tst b bl bx %w(adc add and bic eor orr rsb rsc sbc sub mov mvn cmn cmp teq tst b bl bx
@ -68,23 +66,13 @@ module Asm
} }
} }
def label
Asm::Arm::GeneratorLabel.new(self)
end
def label!
lbl = Asm::Arm::GeneratorLabel.new(self)
lbl.set!
lbl
end
#externs dropped for now #externs dropped for now
def extern(sym) def extern(sym)
if (lbl = @externs.find { |extern| extern.name == sym }) if (lbl = @externs.find { |extern| extern.name == sym })
lbl lbl
else else
@externs << lbl = Asm::Arm::GeneratorExternLabel.new(sym) @externs << lbl = Asm::Arm::GeneratorExternLabel.new(sym)
add_object lbl add_value lbl
lbl lbl
end end
end end

View File

@ -11,7 +11,8 @@ class Asm::Arm::GeneratorLabel < Asm::LabelObject
0 0
end end
def set! def set!
@asm.add_object self @asm.add_value self
self
end end
end end

View File

@ -84,7 +84,7 @@ module Asm
@operand = rm_ref | (shift_op << 4) | (shift_imm << 4+3) @operand = rm_ref | (shift_op << 4) | (shift_imm << 4+3)
else else
raise Asm::AssemblyError.new(Asm::ERRSTR_INVALID_ARG, arg) raise Asm::AssemblyError.new(Asm::ERRSTR_INVALID_ARG + " " + arg.inspect, arg)
end end
end end

View File

@ -5,22 +5,44 @@ module Asm
class Assembler class Assembler
def initialize def initialize
@objects = [] @values = []
@position = -1 # marks not set @position = -1 # marks not set
@label_objects = [] @labels = []
@string_table = {}
#@relocations = [] #@relocations = []
end end
attr_reader :relocations, :objects , :position attr_reader :relocations, :values , :position
def add_object(obj) def add_string str
obj.at(@position) value = @string_table[str]
@position += obj.length return value if value
@objects << obj data = Asm::DataObject.new(str)
add_value data
@string_table[str] = data
end end
def strings
@string_table.values
end
def add_value(val)
val.at(@position)
@position += val.length
@values << val
end
def label
label = Asm::Arm::GeneratorLabel.new(self)
@labels << label
label
end
def label!
label.set!
end
def assemble(io) def assemble(io)
@objects.each do |obj| @values.each do |obj|
obj.assemble io, self obj.assemble io, self
end end
end end
@ -38,7 +60,7 @@ module Asm
#old assemble function #old assemble function
#def assemble(io) #def assemble(io)
# @objects.each do |obj| # @values.each do |obj|
# obj.assemble io, self # obj.assemble io, self
# end # end
# @relocations.delete_if do |reloc| # @relocations.delete_if do |reloc|

View File

@ -9,16 +9,17 @@ class TestExtern < MiniTest::Test
end end
def test_extern def test_extern
hello = "Hello Raisa"+ "\n\x00"
@generator.instance_eval { @generator.instance_eval {
mov r7, 4 #4 == write mov r7, 4 #4 == write
mov r0 , 1 #stdout mov r0 , 1 #stdout
add r1 , pc , 12 # address of "hello Raisa" add r1 , pc , hello # address of "hello Raisa"
mov r2 , 12 # length of hello mov r2 , 12 # length of hello
swi 0 swi 0
mov r7, 1 #1 == exit mov r7, 1 #1 == exit
swi 0 swi 0
} }
@generator.add_data("Hello Raisa"+ "\n\x00") @generator.add_string(hello)
write(7 , 'label') write(7 , 'label')
end end
#helper to write the file #helper to write the file

View File

@ -21,10 +21,10 @@ module Asm
count = m ? m[0].length : 0 count = m ? m[0].length : 0
label_breadcrumb = label_breadcrumb[0,count] label_breadcrumb = label_breadcrumb[0,count]
label_breadcrumb << cmd.name[count..-1] label_breadcrumb << cmd.name[count..-1]
@asm.add_object object_for_label(label_breadcrumb.join('/')) @asm.add_value object_for_label(label_breadcrumb.join('/'))
elsif (cmd.is_a?(Asm::InstructionNode)) elsif (cmd.is_a?(Asm::InstructionNode))
inst = @asm_arch::Instruction.new(cmd, self) inst = @asm_arch::Instruction.new(cmd, self)
@asm.add_object inst @asm.add_value inst
@inst_label_context[inst] = label_breadcrumb @inst_label_context[inst] = label_breadcrumb
elsif (cmd.is_a?(Asm::DirectiveNode)) elsif (cmd.is_a?(Asm::DirectiveNode))
if (cmd.name == 'global') if (cmd.name == 'global')
@ -35,12 +35,12 @@ module Asm
bytes = cmd.value.strip.split(/\s+/).map do |hex| bytes = cmd.value.strip.split(/\s+/).map do |hex|
hex.to_i(16) hex.to_i(16)
end.pack('C*') end.pack('C*')
@asm.add_object Asm::DataObject.new(bytes) @asm.add_value Asm::DataObject.new(bytes)
elsif (cmd.name == "asciz") elsif (cmd.name == "asciz")
str = eval(cmd.value) + "\x00" str = eval(cmd.value) + "\x00"
@asm.add_object Asm::DataObject.new(str) @asm.add_value Asm::DataObject.new(str)
elsif (defined?(Asm::Arm) and cmd.name == 'addrtable') elsif (defined?(Asm::Arm) and cmd.name == 'addrtable')
@asm.add_object Asm::Arm::AddrTableObject.new @asm.add_value Asm::Arm::AddrTableObject.new
else else
raise Asm::AssemblyError.new('unknown directive', cmd) raise Asm::AssemblyError.new('unknown directive', cmd)
end end

View File

@ -13,7 +13,7 @@ if (__FILE__ == $0)
swi 0 swi 0
} }
gen.add_data("printf"+ "\x00") gen.add_string("printf"+ "\x00")
require 'asm/object_writer' require 'asm/object_writer'
writer = Asm::ObjectWriter.new(Elf::Constants::TARGET_ARM) writer = Asm::ObjectWriter.new(Elf::Constants::TARGET_ARM)
writer.set_text gen.assemble_to_string writer.set_text gen.assemble_to_string