0
点赞
收藏
分享

微信扫一扫

CSAPP实验之单周期Y86_64指令模拟器(python版)

ZMXQQ233 2022-03-25 阅读 15
python

#LYQ Y86-64 single_cycle-ISA

imem = [''] * 1000      #指令存储

dmem = [0] * 1000       #数据存储

reg = [0] * 15          #寄存器存储

reg[4] = 750            #rsp栈位置 取dmem中的一段作为栈空间

pReg = 0

iReg = ''

Stat = 1

#CC

ZF = 0

SF = 0

OF = 0


 

def get_V_D(instr):

    return str(instr[14]+instr[15]+instr[12]+instr[13]+instr[10]+instr[11]+instr[8]+instr[9]+instr[6]+instr[7]+instr[4]+instr[5])

def get_Dest(instr):

    return str(instr[12]+instr[13]+instr[10]+instr[11]+instr[8]+instr[9]+instr[6]+instr[7]+instr[4]+instr[5]+instr[2]+instr[3])

def loadProgram(file):

    global pReg, iReg, reg, imem, dmem, Stat, ZF, SF, OF

    fil = open(file, 'r')

    first = True

    while True:

        line = fil.readline()               # 指令+指令地址 (字符串)

        if line == '':

            break

        fids = line.split()                 # 指令+指令地址 (列表)

        address = int(fids[0],16)           # 指令地址

        instruc = fids[1]                   # 指令 (字符串)

        imem[address] = instruc             # 将指令存入imem

        if first:                           # PC寄存器初始化

            pReg = address

            first = False

    fil.close()

def cycle():

    global pReg, iReg, reg, imem, dmem, Stat, ZF, SF, OF

    # 取指令

    iReg = imem[pReg]     # 指令寄存器

    pReg = pReg + 1       # PC寄存器

   

    # 译码、执行和写结果

    instr = list(iReg)                      # 指令(列表)

    opcode = int(instr[0],16)

    opfunction = int(instr[1],16)

    if opcode == 0 :                        #halt

        Stat = 2

    elif opcode == 1 :                      #nop

        1==1

    elif opcode == 9 :                      #ret

        pReg = dmem[reg[4]]

        reg[4] = reg[4] + 8

    else:

        rA = int(instr[2],16)

        rB = int(instr[3],16)

        if   opcode == 2 :                  #rrmovq rA,rB

            reg[rB] = reg[rA]

        elif opcode == 3 :                  #irmovq V,rB

            V = int(get_V_D(instr),16)

            reg[rB] = V

        elif opcode == 4 :                  #rmmovq rA,D(rB)

            D = int(get_V_D(instr),16)

            dmem[D+rB] = reg[rA]

        elif opcode == 5 :                  #mrmovq D(rB),rA

            D = int(get_V_D(instr),16)

            reg[rA] = dmem[D+rB]

        elif opcode == 6 :                  #OPq rA,rB

            fn = opfunction

            if   (fn==0):                       #addq

                reg[rB] = reg[rB] + reg[rA]

            elif (fn==1):                       #subq

                reg[rB] = reg[rB] - reg[rA]

            elif (fn==2):                       #andq

                reg[rB] = reg[rB] & reg[rA]

            elif (fn==3):                       #xorq

                reg[rB] = reg[rB] ^ reg[rA]

            #set CC

            ZF = 1 if reg[rB] == 0 else 0

            SF = 1 if reg[rB] < 0 else 0

           

        elif opcode == 7:                   #jXX

            fn = opfunction

            Dest = int(get_Dest(instr),16)

            if   (fn==0):                       #jmp

                pReg = Dest

            elif (fn==1):                       #jle

                if (SF^OF)|ZF:

                    pReg = Dest

            elif (fn==2):                       #jl

                if SF^OF:

                    pReg = Dest

            elif (fn==3):                       #je

                if ZF==1:

                    pReg = Dest

            elif (fn==4):                       #jne

                if ZF==0:

                    pReg = Dest

            elif (fn==5):                       #jge

                if (SF^OF)==0:

                    pReg = Dest

            elif (fn==6):                       #jg

                if ((SF^OF)==0)&(ZF==0):

                    pReg = Dest

        elif opcode == 8:                   #call Dest

            Dest = int(get_Dest(instr),16)

            pReg = Dest

            reg[4] = reg[4] - 8

            dmem[reg[4]] = reg[rA]

        elif opcode == 10:                  #pushq rA

            reg[4] = reg[4] - 8

            dmem[reg[4]] = reg[rA]

        elif opcode == 11:                  #popq rA

            reg[rA] = dmem[reg[4]]

            reg[4] = reg[4] + 8

        elif opcode == 15:

            print("output:",reg[rA])

        else:

            Stat = 4

    return True

def run(file):

    global pReg, iReg, reg, imem, dmem, Stat, ZF, SF, OF

    loadProgram(file)

    while True:

        cycle()

        if Stat == 2:

            print("HALT")

            break

        if Stat == 4:

            print("INS")

            break

run('1_100sigma.Y86_64')



 

'''

Appendix

***********************************************************************

1_100sigma Y86-64 assembly instruction

    irmovq $1,%r8       //const

    irmovq $1,%rsi      //adder

    irmovq $100,%r9     //counter

    xorq   %rax,%rax    //result

loop:

    addq   %rsi,%rax

    addq   %r8,%rsi

    subq   %r8,%r9

    jne    loop

    output %rax

    halt

***********************************************************************

1_100sigma.Y86_64

0 30F80100000000000000    irmovq $1,%r8       //const

1 30F60100000000000000    irmovq $1,%rsi      //adder

2 30F96400000000000000    irmovq $100,%r9     //counter

3 6300                    xorq   %rax,%rax    //result

4 6060                    addq   %rsi,%rax              loop

5 6086                    addq   %r8,%rsi

6 6189                    subq   %r8,%r9

7 740400000000000000      jne    loop

8 F00F                    output %rax

9 00                      halt

'''

举报

相关推荐

0 条评论