fix positioning and the assembly works

This commit is contained in:
Torsten Ruger 2018-03-29 18:03:21 +03:00
parent 34b16a2332
commit e012f16d7f
6 changed files with 33 additions and 21 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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