clean and work on labels

This commit is contained in:
Torsten Ruger 2014-04-21 17:27:05 +03:00
parent f0c0166d1f
commit ff38bde44e
7 changed files with 70 additions and 54 deletions

View File

@ -18,9 +18,15 @@ First instructions are in fact assembling correctly. Meaning i have tests, and i
Step 2
------
Package the code into an executable. Run that and verufy it's output.
Package the code into an executable. Run that and verify it's output. But full elf support (including externs) is eluding me for now.
Currently hangin on the elf format.
Still, this has proven to be a good review point for the arcitecture and means no libc for now.
Full rationale on the web (pages rep for now), but it means starting an extra step
Step 2.1
--------
Start implementing syscalls and the functionality we actually need from c (basic io only really)
Step 3
-------

View File

@ -1,34 +1,39 @@
class Asm::Arm::AddrTableObject
def initialize
@table = []
@const = []
end
module Asm
module Arm
class AddrTableObject
def initialize
@table = []
@const = []
end
# TODO don't create new entry if there's already an entry for the same label/const
def add_label(label)
d = [label, Asm::LabelObject.new]
@table << d
d[1]
end
# TODO don't create new entry if there's already an entry for the same label/const
def add_label(label)
d = [label, Asm::LabelObject.new]
@table << d
d[1]
end
def add_const(const)
d = [const, Asm::LabelObject.new]
@const << d
d[1]
end
def add_const(const)
d = [const, Asm::LabelObject.new]
@const << d
d[1]
end
def assemble(io, as)
@table.each do |pair|
target_label, here_label = *pair
here_label.assemble io, as
as.add_relocation io.tell, target_label, Asm::Arm::R_ARM_ABS32,
Asm::Arm::Instruction::RelocHandler
io.write_uint32 0
end
@const.each do |pair|
const, here_label = *pair
here_label.assemble io, as
io.write_uint32 const
def assemble(io, as)
@table.each do |pair|
target_label, here_label = *pair
here_label.assemble io, as
as.add_relocation io.tell, target_label, Asm::Arm::R_ARM_ABS32,
Asm::Arm::Instruction::RelocHandler
io.write_uint32 0
end
@const.each do |pair|
const, here_label = *pair
here_label.assemble io, as
io.write_uint32 const
end
end
end
end
end
end

View File

@ -1,5 +1,5 @@
require 'asm/assembler'
require "asm/arm/addr_table_object"
module Asm
module Arm

View File

@ -29,12 +29,12 @@ module Asm
# Build representation for target address
def build_operand(arg)
#str / ldr are _seruous instructions. With BIG possibilities no half are implemented
@i = 0
@pre_post_index = 0
@w = 0
@operand = 0
if (arg.is_a?(Asm::RegisterArgNode))
@i = 0
@pre_post_index = 0
@w = 0
@rn = reg_ref(arg)
@operand = 0
if (false ) #argr.op and argr.right.is_a?(Asm::NumLiteralArgNode))
@ -55,17 +55,13 @@ module Asm
else
# raise Asm::AssemblyError.new(Asm::ERRSTR_INVALID_ARG, arg)
end
elsif (arg.is_a?(Asm::LabelEquivAddrArgNode) or arg.is_a?(Asm::NumEquivAddrArgNode))
@i = 0
elsif (arg.is_a?(Asm::LabelRefArgNode) or arg.is_a?(Asm::NumEquivAddrArgNode))
@pre_post_index = 1
@w = 0
@rn = 15 # pc
@operand = 0
@use_addrtable_reloc = true
@addrtable_reloc_target = arg
else
puts "Invalid #{arg.inspect}"
raise Asm::AssemblyError.new(Asm::ERRSTR_INVALID_ARG, arg.inspect)
raise Asm::AssemblyError.new(Asm::ERRSTR_INVALID_ARG + " " + arg.inspect, arg.inspect)
end
end
@ -81,7 +77,7 @@ module Asm
(pre_post_index << 12+4+4+1+1+1+1) | (i << 12+4+4+1+1+1+1+1) |
(inst_class << 12+4+4+1+1+1+1+1+1) | (cond << 12+4+4+1+1+1+1+1+1+2)
if (@use_addrtable_reloc)
closest_addrtable = Asm::Arm.closest_addrtable(as)
# closest_addrtable = Asm::Arm.closest_addrtable(as)
if (@addrtable_reloc_target.is_a?(Asm::LabelEquivAddrArgNode))
obj = ast_asm.object_for_label(@addrtable_reloc_target.label, inst)
ref_label = closest_addrtable.add_label(obj)

View File

@ -17,7 +17,9 @@ module Asm
end
def add_relocation(*args)
@relocations << Asm::Relocation.new(*args)
reloc = Asm::Relocation.new(*args)
raise "reloc #{reloc.inspect}"
@relocations << reloc
end
def assemble(io)
@ -27,6 +29,7 @@ module Asm
@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

View File

@ -8,18 +8,25 @@ class TestExtern < MiniTest::Test
@generator = Asm::Arm::CodeGenerator.new
end
def test_generate_small
def test_extern
@generator.instance_eval {
ldr r0, "hello world" #1
bl :printf #2
mov r7, 1 #3
swi 0 #4 4 instruction x 4 == 16
push lr
ldr r0, "hello world".to_sym
mov r7, 4 #4 is write
swi 0
pop pc
mov r7, 1 #1 == exit
swi 0
}
write(7 , 'label')
end
#helper to write the file
def write len ,name
writer = Asm::ObjectWriter.new(Elf::Constants::TARGET_ARM)
assembly = @generator.assemble
assert_equal 20 , assembly.length
assert_equal len * 4 , assembly.length
writer.set_text assembly
writer.save('small_test.o')
writer.save("#{name}_test.o")
end
end

View File

@ -15,8 +15,7 @@ class TestSmallProg < MiniTest::Test
def test_generate_small
@generator.instance_eval {
mov r0, 5 #1
loop_start = label
loop_start.set!
loop_start = label!
subs r0, r0, 1 #2
bne loop_start #3
mov r7, 1 #4
@ -48,6 +47,6 @@ class TestSmallProg < MiniTest::Test
assembly = @generator.assemble
assert_equal len * 4 , assembly.length
writer.set_text assembly
writer.save('#{name}_test.o')
writer.save("#{name}_test.o")
end
end