Very simple Assembler

Post your FreeBASIC source, examples, tips and tricks here. Please don’t post code without including an explanation.
Post Reply
nimdays
Posts: 236
Joined: May 29, 2014 22:01
Location: West Java, Indonesia

Very simple Assembler

Post by nimdays »

Code: Select all

type tok
    id as string * 3
    value as string
end type
type hld
    p as ushort
    id as string
    v as string ' idk without this error
end type

dim shared org as ushort
dim shared result as string
dim shared i as uinteger
dim shared x as uinteger=1
dim shared t as uinteger
dim shared token()as tok
dim shared h as ushort
dim shared hold()as hld

sub on_hold(p as ushort,id as string)
    h += 1
    redim preserve hold(1 to h)as hld
    hold(h).p = p
    hold(h).id = id
end sub

sub add_token(id as string,value as string)
    t += 1
    redim preserve token(1 to t)
    token(t).id = id
    token(t).value = value
end sub

function is_num(c as ubyte)as ubyte
    return c >= 48 and c <= 57
end function

function is_char(c as ubyte)as ubyte
    return c >= 97 and c <= 122 or c >= 65 and c <= 90
end function

sub parse1()
   if x >= ubound(token) then exit sub  
   dim rt as ubyte '= 0
   dim reg(15)as string = {"al","cl","dl","bl","ah","ch","dh","bh",_
                          "ax","cx","dx","bx","sp","bp","si","di"}
   if token(x).id = "IDT" then
      if token(x).value = "org" then 
         x += 1 
         org = val(token(x).value )
      elseif token(x).value = "mov" then
         x += 1 'destination
         for r as ubyte = 0 to ubound(reg)
         if reg(r) = token(x).value then
          result += chr(&hB0 + r)'machine code for al = &hB0,cl=&hB1...etc
          rt = r 'save the reg position
         end if 
        next r
        x += 2 'source
        if token(x).id = "IDT" then 'if var
           'put to queue 
           on_hold(len(result),token(x).value)
        end if
        if rt < 8 then '8 bit reg
          result += chr(lobyte(token(x).value))
        else '16 bit reg
          result += chr(lobyte(token(x).value)) + chr(hibyte(token(x).value))
        end if
     elseif token(x).value ="int" then  
        result += chr(&hcd)
        x += 1 'int number 0 - 255
        result += chr(lobyte(token(x).value))
     elseif token(x).value ="db" then 
       x += 1  
       if token(x-2).id = "IDT" then 'check var
          for r as ubyte = 0 to ubound(hold)
             if token(x-2).value  = hold(r).id then
                'update the bytes 
                result[hold(r).p] = lobyte(len(result)+org)
                result[(hold(r).p)+1] = hibyte(len(result)+org)
             end if    
          next r    
       end if 
       result += token(x).value 
     else
       'x += 1 
     end if   
  end if
  x += 1
  parse1()
end sub

sub parse(s as string)
    if i >= len(s) then parse1() :exit sub
    dim buff as string
    if is_num(s[i]) then 'numeric & hex
        while is_num(s[i]) or is_char(s[i])
           buff += chr(s[i]) 
           i += 1
        wend
        'if hex then convert it
        if right(buff,1)="h" then buff = str(val("&h" & buff))
        add_token("NUM",buff)
        buff = ""
    elseif is_char(s[i]) then 'char a-z A-Z
        while is_char(s[i])
           buff += chr(s[i]) 
           i += 1  
        wend
        i -= 1
        add_token("IDT",buff)
        buff = ""
    elseif s[i]= 39  then 'string
        if instr(i+1,s,"'") then
          i += 1   
          while s[i]<> 39
           buff += chr(s[i])
           i += 1
          wend
          add_token("STR",buff)
          buff = ""
        end if  
    elseif s[i]= 44 or s[i]= 59 then 'deliminator
       add_token("DEL",chr(s[i])) 
    else
        'i += 1
    end if
    i += 1
    parse(s)
end sub
 
parse("org 256;mov dx,msg; mov ah,9; int 21h;int 20h; msg db 'Hello World$';")
open "d:\test.com" for binary access write as #1
  put #1,,result
close #1
shell "d:\test.com"
sleep
Last edited by nimdays on Jun 27, 2014 22:20, edited 1 time in total.
bcohio2001
Posts: 556
Joined: Mar 10, 2007 15:44
Location: Ohio, USA
Contact:

Re: Very simple Assembler

Post by bcohio2001 »

Interesting start, but a few suggestions.
1) While iterating/looping, go ahead and use Integer.
2) Find a listing of 'op codes' and create an array for them.
Example: (not correct)
token(0) = "nop"
...
token(23) = "mov"
token(24) = "mov"
....
token(135) = "jmp"
token(136) = "jnz"
token .....

If I remember my assembler correctly, one 'mov' is for a byte move, and the other is for a 'word'/short
3) You also have other registers.
16 bit: ES, DS, CS, SS, AX, BX, CX, DX
nimdays
Posts: 236
Joined: May 29, 2014 22:01
Location: West Java, Indonesia

Re: Very simple Assembler

Post by nimdays »

bcohio2001 wrote:Interesting start, but a few suggestions.
1) While iterating/looping, go ahead and use Integer.
2) Find a listing of 'op codes' and create an array for them.
Example: (not correct)
token(0) = "nop"
...
token(23) = "mov"
token(24) = "mov"
....
token(135) = "jmp"
token(136) = "jnz"
token .....

If I remember my assembler correctly, one 'mov' is for a byte move, and the other is for a 'word'/short
3) You also have other registers.
16 bit: ES, DS, CS, SS, AX, BX, CX, DX
Thanks , 16 bit reg added and integer for looping
About array for opcode , still thinking the right formula for that or maybe you have an example
1st post updated
BasicCoder2
Posts: 3906
Joined: Jan 01, 2009 7:03
Location: Australia

Re: Very simple Assembler

Post by BasicCoder2 »

May I ask what it is you are trying to do?
Is this some kind of work assignment for the use of the token() thingy or something?
The way you are going about it may not expand well as you add more instructions.
A long time ago when I still used assembler I wrote an editor/assembler for the C64 but the 6502 instruction set was fairly simple.
I began with an editor first from which you could call the assembler.
Then you have a set of example source code to test your assembler.
You can start off first with a subset of instructions only found in your test source code.
You can then add code to your assembler as you increase the instructions used in the source code.
A simple start might be a subset of the 16 bit x86 instruction set.
http://sparksandflames.com/files/x86Ins ... Chart.html
bcohio2001
Posts: 556
Joined: Mar 10, 2007 15:44
Location: Ohio, USA
Contact:

Re: Very simple Assembler

Post by bcohio2001 »

I agree with BasicCoder2, I think that you should have a separate file for you 'source asm'.
And read each line to parse.
That is the way you program in FreeBasic, separate line for each command. And in "MASM", an OLD program that was around in the 80's.

This is going from memory, so:
Source code is divided into 4 'zones', separated by the tab character.
1) Label or command to parser
2) Operation or the parameter to parser
3) Operator
4) Comment area

Give me a little bit to get something going to get you started.
nimdays
Posts: 236
Joined: May 29, 2014 22:01
Location: West Java, Indonesia

Re: Very simple Assembler

Post by nimdays »

Thank you both , very constructive comments :)
I will find some source code to learn again.
Post Reply