2014-04-19 22:25:46 +02:00
|
|
|
require_relative "relocation"
|
|
|
|
|
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
|
|
|
|
@objects = []
|
|
|
|
@label_objects = []
|
|
|
|
@relocations = []
|
|
|
|
end
|
|
|
|
attr_reader :relocations, :objects
|
|
|
|
|
|
|
|
def add_object(obj)
|
|
|
|
@objects << obj
|
|
|
|
end
|
|
|
|
|
|
|
|
def add_relocation(*args)
|
2014-04-21 16:27:05 +02:00
|
|
|
reloc = Asm::Relocation.new(*args)
|
2014-04-21 16:34:24 +02:00
|
|
|
#raise "reloc #{reloc.inspect}"
|
2014-04-21 16:27:05 +02:00
|
|
|
@relocations << reloc
|
2014-04-14 17:09:56 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
def assemble(io)
|
|
|
|
@objects.each do |obj|
|
|
|
|
obj.assemble io, self
|
|
|
|
end
|
|
|
|
|
|
|
|
@relocations.delete_if do |reloc|
|
|
|
|
io.seek reloc.position
|
2014-04-21 16:34:24 +02:00
|
|
|
#puts "reloc #{reloc.inspect}"
|
2014-04-14 17:09:56 +02:00
|
|
|
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
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|