2014-04-19 22:25:46 +02:00
|
|
|
|
2014-04-14 17:09:56 +02:00
|
|
|
module Asm
|
|
|
|
ERRSTR_NUMERIC_TOO_LARGE = 'cannot fit numeric literal argument in operand'
|
|
|
|
ERRSTR_INVALID_ARG = 'invalid operand argument'
|
|
|
|
|
|
|
|
class Assembler
|
|
|
|
def initialize
|
2014-04-22 21:24:22 +02:00
|
|
|
@values = []
|
2014-04-22 22:35:15 +02:00
|
|
|
@position = 0 # marks not set
|
2014-04-22 21:24:22 +02:00
|
|
|
@labels = []
|
|
|
|
@string_table = {}
|
2014-04-22 10:58:17 +02:00
|
|
|
#@relocations = []
|
2014-04-14 17:09:56 +02:00
|
|
|
end
|
2014-04-22 21:24:22 +02:00
|
|
|
attr_reader :relocations, :values , :position
|
2014-04-14 17:09:56 +02:00
|
|
|
|
2014-04-22 21:24:22 +02:00
|
|
|
def add_string str
|
|
|
|
value = @string_table[str]
|
|
|
|
return value if value
|
2014-04-22 23:12:43 +02:00
|
|
|
data = Asm::StringNode.new(str)
|
2014-04-22 21:24:22 +02:00
|
|
|
@string_table[str] = data
|
2014-04-14 17:09:56 +02:00
|
|
|
end
|
2014-04-21 20:21:45 +02:00
|
|
|
|
2014-04-22 21:24:22 +02:00
|
|
|
def strings
|
|
|
|
@string_table.values
|
|
|
|
end
|
|
|
|
|
|
|
|
def add_value(val)
|
|
|
|
val.at(@position)
|
2014-04-22 22:35:15 +02:00
|
|
|
length = val.length
|
|
|
|
@position += length
|
2014-04-22 21:24:22 +02:00
|
|
|
@values << val
|
|
|
|
end
|
|
|
|
|
|
|
|
def label
|
|
|
|
label = Asm::Arm::GeneratorLabel.new(self)
|
|
|
|
@labels << label
|
|
|
|
label
|
|
|
|
end
|
|
|
|
|
|
|
|
def label!
|
|
|
|
label.set!
|
|
|
|
end
|
2014-04-14 17:09:56 +02:00
|
|
|
|
|
|
|
def assemble(io)
|
2014-04-22 21:24:22 +02:00
|
|
|
@values.each do |obj|
|
2014-04-14 17:09:56 +02:00
|
|
|
obj.assemble io, self
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2014-04-21 20:38:39 +02:00
|
|
|
|
|
|
|
# class Relocation
|
|
|
|
# def initialize(pos, label, type, handler)
|
|
|
|
# @position = pos
|
|
|
|
# @label = label
|
|
|
|
# @type = type
|
|
|
|
# @handler = handler
|
|
|
|
# end
|
|
|
|
# attr_reader :position, :label, :type, :handler
|
|
|
|
# end
|
|
|
|
|
|
|
|
#old assemble function
|
|
|
|
#def assemble(io)
|
2014-04-22 21:24:22 +02:00
|
|
|
# @values.each do |obj|
|
2014-04-21 20:38:39 +02:00
|
|
|
# obj.assemble io, self
|
|
|
|
# end
|
|
|
|
# @relocations.delete_if do |reloc|
|
|
|
|
# io.seek reloc.position
|
|
|
|
# #puts "reloc #{reloc.inspect}"
|
|
|
|
# if (reloc.label.extern?)
|
|
|
|
# reloc.handler.call(io, io.tell, reloc.type)
|
|
|
|
# else
|
|
|
|
# reloc.handler.call(io, reloc.label.address, reloc.type)
|
|
|
|
# end
|
|
|
|
# not reloc.label.extern?
|
|
|
|
#end
|
|
|
|
#end
|
|
|
|
#def add_relocation(*args)
|
|
|
|
# reloc = Asm::Relocation.new(*args)
|
|
|
|
# #raise "reloc #{reloc.inspect}"
|
|
|
|
# @relocations << reloc
|
|
|
|
#end
|
|
|
|
|
2014-04-14 17:09:56 +02:00
|
|
|
end
|
|
|
|
|