diff --git a/README.md b/README.md index 58b46e3d..cc90c8a9 100644 --- a/README.md +++ b/README.md @@ -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 ------- diff --git a/lib/asm/arm/addr_table_object.rb b/lib/asm/arm/addr_table_object.rb index 13c16dd9..a56d6046 100644 --- a/lib/asm/arm/addr_table_object.rb +++ b/lib/asm/arm/addr_table_object.rb @@ -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 \ No newline at end of file diff --git a/lib/asm/arm/arm_assembler.rb b/lib/asm/arm/arm_assembler.rb index d71b7255..3d8494f4 100644 --- a/lib/asm/arm/arm_assembler.rb +++ b/lib/asm/arm/arm_assembler.rb @@ -1,5 +1,5 @@ require 'asm/assembler' - +require "asm/arm/addr_table_object" module Asm module Arm diff --git a/lib/asm/arm/memory_access_builder.rb b/lib/asm/arm/memory_access_builder.rb index 38aa93fa..ac09faac 100644 --- a/lib/asm/arm/memory_access_builder.rb +++ b/lib/asm/arm/memory_access_builder.rb @@ -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) diff --git a/lib/asm/assembler.rb b/lib/asm/assembler.rb index 3a2a8d3f..7815225a 100644 --- a/lib/asm/assembler.rb +++ b/lib/asm/assembler.rb @@ -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 diff --git a/test/extern_test.rb b/test/label_test.rb similarity index 51% rename from test/extern_test.rb rename to test/label_test.rb index 9129e5b9..a810d6e5 100644 --- a/test/extern_test.rb +++ b/test/label_test.rb @@ -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 diff --git a/test/small_program_test.rb b/test/small_program_test.rb index cb2b1628..3fd302bf 100644 --- a/test/small_program_test.rb +++ b/test/small_program_test.rb @@ -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