java - pass1汇编器的符号表

标签 java assembly symbol-table

我想为IBM360汇编语言设计一个简单的汇编器。所以我首先实现符号表。我将符号/标签存储在一个单独的文件中,以便在生成符号表时进行比较。我面临的问题是,由于不需要的比较而导致位置计数器(LC)值不正确。我能够检测到符号但 LC 值错误。谁能指导我修改我的代码?

这是我的程序:

import java.io.*; 
import java.lang.*; 

class SymbolTable
 { 
    public static void main(String args[]) throws Exception 
    { 
    FileReader fr = new FileReader("program.asm"); 
    BufferedReader br = new BufferedReader(fr); 
    String s,l; 
    String code[]=new String[100];
    String label[]=new String[100];

    int N=0,i,LOC=0,n=0,j;
    System.out.println("Assembly lang program :\n--------------------------");
    while((s = br.readLine()) != null)
    {
        code[N++]=s;
        System.out.println(s); 
    } 
    fr.close();
    FileReader labels = new FileReader("label.txt"); 
    BufferedReader buff = new BufferedReader(labels); 
    while((s = buff.readLine()) != null)
    {
        label[n++]=s;
    } 
    labels.close();
    System.out.println("\n\n SYMBOL TABLE :\n-------------------------------------------\nLABEL\tLC\tLENGTH\tRELATIVE/ABSOLUTE\n-------------------------------------------");
    for(i=0;i<N;i++)
    {
        for(j=0;j<n;j++)
        {           
                char codearr[]=new char[15];
                codearr=code[i].toCharArray();
                if(code[i].startsWith("USING"))
                {
                 break;
                }
                else if(code[i].startsWith(label[j]))
                {
                    System.out.println(label[j]+"\t"+LOC+"\t4\tR");
                    if(i==0)
                    {}
                    else
                    LOC=LOC+4;
                    break;                  
                }
                else if(codearr[1]=='R')   // for register addressing mode
                    LOC=LOC+2;
                else
                    LOC=LOC+4;
        }   
    }
    } 
 }

程序.asm:

JOHN START 
USING *,15
L 1,FIVE
A 1,FOUR
ST 1,TEMP
FOUR DC F '4'
FIVE DC F '5'
TEMP DS 1F
END

标签.txt

JOHN
FOUR 
FIVE
TEMP

输出:

G:\programs>javac SymbolTable.java
G:\programs>java SymbolTable
Assembly lang program :
--------------------------
JOHN START
USING *,15
LR 1,FIVE
A 1,FOUR
ST 1,TEMP
FOUR DC F '4'
FIVE DC F '5'
TEMP DS 1F
END

 SYMBOL TABLE :
-------------------------------------------
LABEL   LC      LENGTH  RELATIVE/ABSOLUTE
-------------------------------------------
JOHN    0       4       R
FOUR    44      4       R
FIVE    56      4       R
TEMP    72      4       R

最佳答案

这里有一个示例可以帮助您了解方法。我不知道语言的来龙去脉,但根据您提供的输入,这个示例应该有所帮助。它根据操作码开头匹配的标签构建符号表,我认为这是划分与标签关联的代码部分的正确语法。该代码做出假设并且不会检查可能的冲突,但您可以弄清楚所有这些。请随意构建它。

输入

您提供的确切输入。

输出

JOHN    0   true
FOUR    50  true
TEMP    78  true
FIVE    64  true

代码

import java.io.File;
import java.io.IOException;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;

class SymbolTableBuilder
{
    public static SymbolTable build(String asm, String lbls)
    {
        return build(asm.split("\n"), lbls.split("\n"));
    }

    public static SymbolTable build(String[] asm, String[] lbls)
    {
        return build(Arrays.asList(asm), Arrays.asList(lbls));
    }

    public static SymbolTable build(File asm, File lbls)
    {
        //TODO
        return null;
    }

    public static SymbolTable build(List<String> asm, List<String> lbls)
    {
        SymbolTable tbl = new SymbolTable();
        int pos = 0;
        for (String opCode : asm) {
            String tok = opCode.split("\\s+")[0];
            if (lbls.contains(tok))
                tbl.addSymbol(tok, new Symbol(tok, pos, true));
            pos += opCode.length() + 1; //account for newline
        }
        return tbl;
    }

    public static void main(String[] args) throws IOException
    {
        final String asm
            = "JOHN START\nUSING *,15\nL 1,FIVE\nA 1,FOUR\n"
            + "ST 1,TEMP\nFOUR DC F '4'\nFIVE DC F '5'\nTEMP DS 1F\nEND";

        final String lbls = "JOHN\nFOUR\nFIVE\nTEMP";

        for (Entry<String, Symbol> e : SymbolTableBuilder.build(asm, lbls))
            System.out.println(e.getValue());
    }

}

class SymbolTable implements Iterable<Entry<String, Symbol>>
{
    private Map<String, Symbol> syms;

    public SymbolTable()
    {
        syms = new HashMap<>();
    }

    public void addSymbol(String key, Symbol sym)
    {
        syms.put(key, sym);
    }

    public Symbol getSymbol(String key)
    {
        return syms.get(key);
    }

    @Override
    public Iterator<Entry<String, Symbol>> iterator()
    {
        return syms.entrySet().iterator();
    }
}

class Symbol
{
    String label;
    int loc;
    boolean relative;

    public Symbol(String label, int loc, boolean relative)
    {
        this.label = label;
        this.loc = loc;
        this.relative = relative;
    }

    @Override
    public int hashCode()
    {
        int hash = 3;
        hash = 29 * hash + Objects.hashCode(this.label);
        return hash;
    }

    @Override
    public boolean equals(Object obj)
    {
        if (obj == null) return false;
        if (getClass() != obj.getClass()) return false;
        final Symbol other = (Symbol) obj;
        if (!Objects.equals(this.label, other.label)) return false;
        return true;
    }

    @Override
    public String toString()
    {
        return label + "\t" + loc + "\t" + relative;
    }
}

关于java - pass1汇编器的符号表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21213435/

相关文章:

java - 作为原始类型 ListAdapter 的成员,对submitList(List<T>) 进行未经检查的调用

c++ - 是否应该避免未命名的命名空间函数以减少符号表的大小?

java - 获取拨号器 Intent 的 RESULT_CANCELED

java - SEAM - 获取 base65 认证的 url

c++ - 连接汇编和 C 问题

assembly - 近跳自动改为短跳

C全局静态变量初始化是由链接器完成的?

C++错误: expected primary-expression before 'int'

Java:JPA 实体@OneToMany

c - map exe反编译回C语言