From e012f16d7fc688550bc4decbf576e3982d053311 Mon Sep 17 00:00:00 2001 From: Torsten Ruger Date: Thu, 29 Mar 2018 18:03:21 +0300 Subject: [PATCH] fix positioning and the assembly works --- lib/parfait/binary_code.rb | 2 +- lib/parfait/data_object.rb | 6 +++--- lib/risc/assembler.rb | 3 +-- lib/risc/machine.rb | 37 +++++++++++++++++++++----------- test/parfait/test_binary_code.rb | 2 +- test/risc/test_assembler.rb | 4 ++-- 6 files changed, 33 insertions(+), 21 deletions(-) diff --git a/lib/parfait/binary_code.rb b/lib/parfait/binary_code.rb index 37c147da..7020f5a1 100644 --- a/lib/parfait/binary_code.rb +++ b/lib/parfait/binary_code.rb @@ -25,7 +25,7 @@ module Parfait end def each_word index = 1 - while( index <= 14) + while( index < 14) yield get_internal_word(index) index += 1 end diff --git a/lib/parfait/data_object.rb b/lib/parfait/data_object.rb index 53295951..61f0d3ef 100644 --- a/lib/parfait/data_object.rb +++ b/lib/parfait/data_object.rb @@ -49,7 +49,7 @@ module Parfait 1 end def padded_length - 2 + 2 * 4 end end @@ -58,7 +58,7 @@ module Parfait 7 end def padded_length - 8 + 8 * 4 end end class Data16 < DataObject @@ -66,7 +66,7 @@ module Parfait 15 end def padded_length - 16 + 16 * 4 end end end diff --git a/lib/risc/assembler.rb b/lib/risc/assembler.rb index c8e08444..60a468b3 100644 --- a/lib/risc/assembler.rb +++ b/lib/risc/assembler.rb @@ -8,7 +8,7 @@ module Risc class Assembler include Logging - log_level :debug + log_level :info MARKER = 0xA51AF00D @@ -35,7 +35,6 @@ module Risc all.each do |objekt| next if objekt.is_a?(Risc::Label) log.debug "Linked #{objekt.class}:0x#{objekt.object_id.to_s(16)} at 0x#{Positioned.position(objekt).to_s(16)} / 0x#{objekt.padded_length.to_s(16)}" - Positioned.position(objekt) end end diff --git a/lib/risc/machine.rb b/lib/risc/machine.rb index 088589ea..6d476b20 100644 --- a/lib/risc/machine.rb +++ b/lib/risc/machine.rb @@ -32,7 +32,9 @@ module Risc translate(Arm::Translator.new) end - # translate the methods to whatever cpu the translator translates to + # translate code to whatever cpu the translator translates to + # this means translating the initial jump (cpu_init into binary_init) + # and then translating all methods def translate( translator ) methods = Parfait.object_space.collect_methods translate_methods( methods , translator ) @@ -40,6 +42,7 @@ module Risc @binary_init = Parfait::BinaryCode.new(1) end + # go through all methods and translate them to cpu, given the translator def translate_methods(methods , translator) methods.each do |method| log.debug "Translate method #{method.name}" @@ -52,6 +55,15 @@ module Risc @objects ||= Collector.collect_space end + # To create binaries, objects (and labels) need to have a position + # (so objects can be loaded and branches know where to jump) + # + # Position in the order + # - initial jump + # - all object + # - all code + # As code length amy change during assembly, this way at least the objects stay + # in place and we don't have to deal with chaning loading code def position_all translate_arm unless @translated #need the initial jump at 0 and then functions @@ -63,43 +75,44 @@ module Risc position_code_from( at ) end + # go through everything that is not code (BinaryCode) and set position + # padded_length is what determines an objects (byte) length def position_objects( at ) - at += 8 # thats the padding # want to have the objects first in the executable objects.each do | id , objekt| - case objekt - when Parfait::BinaryCode - when Risc::Label - else - Positioned.set_position(objekt,at) - at += objekt.padded_length - end + next if objekt.is_a?( Parfait::BinaryCode) or objekt.is_a?( Risc::Label ) + Positioned.set_position(objekt,at) + at += objekt.padded_length end at end + # Position all BinaryCode. + # + # So that all code from one method is layed out linearly (for debuggin) + # we go through methods, and then through all codes from the method def position_code_from( at ) objects.each do |id , method| next unless method.is_a? Parfait::TypedMethod log.debug "CODE1 #{method.name}:#{at}" - method.cpu_instructions.set_position( at + 12) # BinaryCode header + method.cpu_instructions.set_position( at ) before = at nekst = method.binary while(nekst) Positioned.set_position(nekst , at) at += nekst.padded_length nekst = nekst.next - #puts "LENGTH #{len}" end log.debug "CODE2 #{method.name}:#{at} len: #{at - before}" end at end + # Create Binary code for all methods and the initial jump + # BinaryWriter handles the writing from instructions into BinaryCode objects def create_binary objects.each do |id , method| next unless method.is_a? Parfait::TypedMethod - #puts "Binary for #{method.name}:#{}" writer = BinaryWriter.new(method.binary) writer.assemble(method.cpu_instructions) end diff --git a/test/parfait/test_binary_code.rb b/test/parfait/test_binary_code.rb index f3722fa4..3f7d038c 100644 --- a/test/parfait/test_binary_code.rb +++ b/test/parfait/test_binary_code.rb @@ -72,7 +72,7 @@ module Parfait def test_each len = 0 @code.each_word{ len += 1} - assert_equal 14 , len + assert_equal 13 , len end end end diff --git a/test/risc/test_assembler.rb b/test/risc/test_assembler.rb index f7efcb2c..ffe57bcb 100644 --- a/test/risc/test_assembler.rb +++ b/test/risc/test_assembler.rb @@ -6,10 +6,10 @@ module Risc def setup @machine = Risc.machine.boot end - def est_init + def test_init @assembler = Assembler.new(@machine) end - def est_write_fails + def test_write_fails @assembler = Assembler.new(@machine) assert_raises{ @assembler.write_as_string} #must translate first end