diff --git a/asm/asm.rb b/asm/asm.rb index 4f4383d..b7037d0 100644 --- a/asm/asm.rb +++ b/asm/asm.rb @@ -12,7 +12,10 @@ module Assembler # implemented to be useful. class AssemblerBase - def initialize(*args) + attr_reader :platform + + def initialize(platform='linux', *args) + @platform = platform @vars = {} # Symbol table, maps names to locations in BSS. @num_labels = 0 # Used to generate unique labels. @num_labels_with_suffix = Hash.new(0) diff --git a/build.rb b/build.rb index c928917..16fedc5 100755 --- a/build.rb +++ b/build.rb @@ -21,10 +21,10 @@ end # filename: input filename # asm: assembler to use # returns: output filename -def compile(filename, asm, binformat='elf') +def compile(filename, asm) File.open(filename, 'r') do |input| - compiler = Compiler.new(input, asm, binformat) + compiler = Compiler.new(input, asm) compiler.compile end @@ -81,7 +81,7 @@ def build(filename, platform='linux', format='asm', binformat='elf') obj = asm( code, binformat ) link( obj, platform ) else # binary - obj = compile(filename, Assembler::Binary.new(platform), binformat) + obj = compile(filename, Assembler::Binary.new(platform)) link( obj, platform ) end return bin diff --git a/compiler.rb b/compiler.rb index 272acd8..5bf9fcf 100644 --- a/compiler.rb +++ b/compiler.rb @@ -29,15 +29,10 @@ class Compiler attr_reader :asm - def initialize(input, asm, binformat='elf') + def initialize(input, asm) # XXX for development only! @indent = 0 # for pretty printing - # The only binary format our assembler knows right now is ELF. - unless binformat == 'elf' - raise "Only ELF is supported. Unsupported binary format: #{binformat}." - end - @look = '' # Next lookahead char. @token = nil # Type of last read token. @value = nil # Value of last read token. @@ -604,11 +599,36 @@ class Compiler dec(:edi) shr(:eax, 8) loop_(loop_label) - mov(:eax, 4) # SYS_write - mov(:ebx, 1) # STDOUT - lea(:ecx, '[HEX]') - mov(:edx, 11) # excluding term, max # of chars to print - int(0x80) + # write(int fd, char *s, int n) + mov(:eax, 4) # SYS_write + lea(:ecx, '[HEX]') # ecx = &s + args = [1, # fd = 1 (STDOUT) + :ecx, # s = &s + 11] # n = 11 (excluding term, max # of chars to print) + case platform + when 'darwin' # on the stack, right to left (right @ highest addr) + #### + # setup bogus stack frame + push(:ebp) + mov(:ebp, :esp) + sub(:esp, 36) + #### + args.reverse.each { |a| push(a) } + push(:eax) + int(0x80) + #### + # teardown bogus stack frame + xor(:eax, :eax) + add(:esp, 36) + pop(:ebx) + emit("leave") + #### + when 'linux' + mov(:ebx, args[0]) + mov(:ecx, args[1]) + mov(:edx, args[2]) + int(0x80) + end end end