From 4b8e342a940d7f9acab635f3953fa074c251a510 Mon Sep 17 00:00:00 2001 From: "Michael D. Lowis" Date: Wed, 17 Jul 2024 23:30:08 -0400 Subject: [PATCH] fixed offset and link logic --- asm.rb | 63 ++++++++++++++++++++++++++++++++++++++-------------------- asm.s | 5 +++++ 2 files changed, 46 insertions(+), 22 deletions(-) diff --git a/asm.rb b/asm.rb index 06ac54b..f25bb20 100755 --- a/asm.rb +++ b/asm.rb @@ -16,13 +16,9 @@ PROG = [ 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # 94 p_filesz: 0x00011E02, (size in bytes of the segment in the file) 0x00, 0x00, 0xC0, 0x7F, 0x00, 0x00, 0x00, 0x00, # 102 p_memsz: 0x7FC00000, (size in bytes of the segment in memory) 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, # 112 - -# 0x48, 0xc7, 0xc0, 0x3C, 0x00, 0x00, 0x00, # mov $0x3c,%rax -# 0x48, 0x31, 0xff, # xor %rdi,%rdi -# 0x0f, 0x05, # syscall ] -Word = Struct.new(:name, :flags, :code) +Word = Struct.new(:name, :addr, :flags, :code) IMM = 1 class Integer @@ -36,11 +32,11 @@ def pop(); $stack.pop(); end def do_word(code); code.each{|w| w.call() }; end def word(name, flags, code) code = code.map{|w| $words[w].code } - $words[name] = Word.new(name, flags, lambda { do_word(code) }) + $words[name] = Word.new(name, nil, flags, lambda { do_word(code) }) end def builtin(name, &code) - $words[name] = Word.new(name, 0, code) + $words[name] = Word.new(name, nil, 0, code) end def call(word) @@ -323,40 +319,63 @@ builtin('word') do end builtin('variable') do - offset = base_offset() call('word') name = pop() - allocation = (3 + ((name.length + 1) / 8.0).ceil) * 8 - value_addr = (offset + PROG.length) - code_addr = offset + (allocation * 8) + # allocate value slot + pack64(0) + + offset = base_offset() + here = PROG.length + + allocation = (2 + ((name.length + 1) / 8.0).ceil) * 8 + value_addr = (here - 8) + code_addr = here + allocation + + pack64(code_addr) # CODE ADDR + if $words['latest'] + pack64($words['latest'].addr) + else + pack64(0) + end - pack64(0) # VALUE - pack64(code_addr) # CODE ADDR - pack64(0) # LINK - TODO: actually link to latest - pack8(name.length) # NAME LEN - packBytes(name.bytes) # NAME + pack8(name.length) # NAME LEN + packBytes(name.bytes) # NAME packPadding(PROG.length % 8) mov_imm(value_addr, 0) # load address packBytes([0x48, 0x8D, 0x6D, 0x08]) # lea 0x8(%rbp),%rbp packBytes([0x48, 0x89, 0x45, 0x00]) # mov %rax,(%rbp) packPadding(PROG.length % 8) + + $words[name] = Word.new(name, here + offset, 0, 0) + $words['latest'].addr = here + offset end builtin('code') do - offset = base_offset() call('word') name = pop() + offset = base_offset() + here = PROG.length + allocation = (2 + ((name.length + 1) / 8.0).ceil) * 8 - code_addr = offset + (allocation * 8) + value_addr = (here - 8) + code_addr = here + allocation - pack64(code_addr) # CODE ADDR - pack64(0) # LINK - TODO: actually link to latest - pack8(name.length) # NAME LEN - packBytes(name.bytes) # NAME + pack64(code_addr) # CODE ADDR + if $words['latest'] + pack64($words['latest'].addr) + else + pack64(0) + end + + pack8(name.length) # NAME LEN + packBytes(name.bytes) # NAME packPadding(PROG.length % 8) + + $words[name] = Word.new(name, here + offset, 0, 0) + $words['latest'].addr = here + offset end builtin('end-code') do diff --git a/asm.s b/asm.s index c848cac..0d6aa47 100644 --- a/asm.s +++ b/asm.s @@ -29,6 +29,11 @@ variable R0 # DEFINE BUILTIN WORDS # ---------------------------------------- +code dummy + 60 rax load-imm + rax push-reg +end-code + # quit: # Loop Forever # r0 -- 2.54.0