clean and work on labels
This commit is contained in:
parent
f0c0166d1f
commit
ff38bde44e
10
README.md
10
README.md
@ -18,9 +18,15 @@ First instructions are in fact assembling correctly. Meaning i have tests, and i
|
|||||||
Step 2
|
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
|
Step 3
|
||||||
-------
|
-------
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
class Asm::Arm::AddrTableObject
|
module Asm
|
||||||
|
module Arm
|
||||||
|
|
||||||
|
class AddrTableObject
|
||||||
def initialize
|
def initialize
|
||||||
@table = []
|
@table = []
|
||||||
@const = []
|
@const = []
|
||||||
@ -31,4 +34,6 @@ class Asm::Arm::AddrTableObject
|
|||||||
io.write_uint32 const
|
io.write_uint32 const
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
@ -1,5 +1,5 @@
|
|||||||
require 'asm/assembler'
|
require 'asm/assembler'
|
||||||
|
require "asm/arm/addr_table_object"
|
||||||
module Asm
|
module Asm
|
||||||
module Arm
|
module Arm
|
||||||
|
|
||||||
|
@ -29,12 +29,12 @@ module Asm
|
|||||||
# Build representation for target address
|
# Build representation for target address
|
||||||
def build_operand(arg)
|
def build_operand(arg)
|
||||||
#str / ldr are _seruous instructions. With BIG possibilities no half are implemented
|
#str / ldr are _seruous instructions. With BIG possibilities no half are implemented
|
||||||
if (arg.is_a?(Asm::RegisterArgNode))
|
|
||||||
@i = 0
|
@i = 0
|
||||||
@pre_post_index = 0
|
@pre_post_index = 0
|
||||||
@w = 0
|
@w = 0
|
||||||
@rn = reg_ref(arg)
|
|
||||||
@operand = 0
|
@operand = 0
|
||||||
|
if (arg.is_a?(Asm::RegisterArgNode))
|
||||||
|
@rn = reg_ref(arg)
|
||||||
|
|
||||||
if (false ) #argr.op and argr.right.is_a?(Asm::NumLiteralArgNode))
|
if (false ) #argr.op and argr.right.is_a?(Asm::NumLiteralArgNode))
|
||||||
|
|
||||||
@ -55,17 +55,13 @@ module Asm
|
|||||||
else
|
else
|
||||||
# raise Asm::AssemblyError.new(Asm::ERRSTR_INVALID_ARG, arg)
|
# raise Asm::AssemblyError.new(Asm::ERRSTR_INVALID_ARG, arg)
|
||||||
end
|
end
|
||||||
elsif (arg.is_a?(Asm::LabelEquivAddrArgNode) or arg.is_a?(Asm::NumEquivAddrArgNode))
|
elsif (arg.is_a?(Asm::LabelRefArgNode) or arg.is_a?(Asm::NumEquivAddrArgNode))
|
||||||
@i = 0
|
|
||||||
@pre_post_index = 1
|
@pre_post_index = 1
|
||||||
@w = 0
|
|
||||||
@rn = 15 # pc
|
@rn = 15 # pc
|
||||||
@operand = 0
|
|
||||||
@use_addrtable_reloc = true
|
@use_addrtable_reloc = true
|
||||||
@addrtable_reloc_target = arg
|
@addrtable_reloc_target = arg
|
||||||
else
|
else
|
||||||
puts "Invalid #{arg.inspect}"
|
raise Asm::AssemblyError.new(Asm::ERRSTR_INVALID_ARG + " " + arg.inspect, arg.inspect)
|
||||||
raise Asm::AssemblyError.new(Asm::ERRSTR_INVALID_ARG, arg.inspect)
|
|
||||||
end
|
end
|
||||||
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) |
|
(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)
|
(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)
|
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))
|
if (@addrtable_reloc_target.is_a?(Asm::LabelEquivAddrArgNode))
|
||||||
obj = ast_asm.object_for_label(@addrtable_reloc_target.label, inst)
|
obj = ast_asm.object_for_label(@addrtable_reloc_target.label, inst)
|
||||||
ref_label = closest_addrtable.add_label(obj)
|
ref_label = closest_addrtable.add_label(obj)
|
||||||
|
@ -17,7 +17,9 @@ module Asm
|
|||||||
end
|
end
|
||||||
|
|
||||||
def add_relocation(*args)
|
def add_relocation(*args)
|
||||||
@relocations << Asm::Relocation.new(*args)
|
reloc = Asm::Relocation.new(*args)
|
||||||
|
raise "reloc #{reloc.inspect}"
|
||||||
|
@relocations << reloc
|
||||||
end
|
end
|
||||||
|
|
||||||
def assemble(io)
|
def assemble(io)
|
||||||
@ -27,6 +29,7 @@ module Asm
|
|||||||
|
|
||||||
@relocations.delete_if do |reloc|
|
@relocations.delete_if do |reloc|
|
||||||
io.seek reloc.position
|
io.seek reloc.position
|
||||||
|
puts "reloc #{reloc.inspect}"
|
||||||
if (reloc.label.extern?)
|
if (reloc.label.extern?)
|
||||||
reloc.handler.call(io, io.tell, reloc.type)
|
reloc.handler.call(io, io.tell, reloc.type)
|
||||||
else
|
else
|
||||||
|
@ -8,18 +8,25 @@ class TestExtern < MiniTest::Test
|
|||||||
@generator = Asm::Arm::CodeGenerator.new
|
@generator = Asm::Arm::CodeGenerator.new
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_generate_small
|
def test_extern
|
||||||
@generator.instance_eval {
|
@generator.instance_eval {
|
||||||
ldr r0, "hello world" #1
|
push lr
|
||||||
bl :printf #2
|
ldr r0, "hello world".to_sym
|
||||||
mov r7, 1 #3
|
mov r7, 4 #4 is write
|
||||||
swi 0 #4 4 instruction x 4 == 16
|
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)
|
writer = Asm::ObjectWriter.new(Elf::Constants::TARGET_ARM)
|
||||||
assembly = @generator.assemble
|
assembly = @generator.assemble
|
||||||
assert_equal 20 , assembly.length
|
assert_equal len * 4 , assembly.length
|
||||||
writer.set_text assembly
|
writer.set_text assembly
|
||||||
writer.save('small_test.o')
|
writer.save("#{name}_test.o")
|
||||||
end
|
end
|
||||||
end
|
end
|
@ -15,8 +15,7 @@ class TestSmallProg < MiniTest::Test
|
|||||||
def test_generate_small
|
def test_generate_small
|
||||||
@generator.instance_eval {
|
@generator.instance_eval {
|
||||||
mov r0, 5 #1
|
mov r0, 5 #1
|
||||||
loop_start = label
|
loop_start = label!
|
||||||
loop_start.set!
|
|
||||||
subs r0, r0, 1 #2
|
subs r0, r0, 1 #2
|
||||||
bne loop_start #3
|
bne loop_start #3
|
||||||
mov r7, 1 #4
|
mov r7, 1 #4
|
||||||
@ -48,6 +47,6 @@ class TestSmallProg < MiniTest::Test
|
|||||||
assembly = @generator.assemble
|
assembly = @generator.assemble
|
||||||
assert_equal len * 4 , assembly.length
|
assert_equal len * 4 , assembly.length
|
||||||
writer.set_text assembly
|
writer.set_text assembly
|
||||||
writer.save('#{name}_test.o')
|
writer.save("#{name}_test.o")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user