⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dis_68k.c

📁 完整的Bell实验室的嵌入式文件系统TFS
💻 C
📖 第 1 页 / 共 3 页
字号:
/* MC68000 Disassembler: *  ELS... *  This disassembler is a hack of the mc68dis disassembler. *  NOTE: this adds approximately 20K to the size of the monitor. * *  General notice: *  This code is part of a boot-monitor package developed as a generic base *  platform for embedded system designs.  As such, it is likely to be *  distributed to various projects beyond the control of the original *  author.  Please notify the author of any enhancements made or bugs found *  so that all may benefit from the changes.  In addition, notification back *  to the author will allow the new user to pick up changes that may have *  been made by other users after this version of the code was distributed. * *  Note1: the majority of this code was edited with 4-space tabs. *  Note2: as more and more contributions are accepted, the term "author" *         is becoming a mis-representation of credit. * *  Original author:    Ed Sutter *  Email:              esutter@lucent.com *  Phone:              908-582-2351 */#include "config.h"#if INCLUDE_DISASSEMBLER#include "cpu.h"#include "ctype.h"#include "genlib.h"#include "stddefs.h"#define NULL 0#define BIT3(x) (int)((x >> 3) & 0x1L)  /* ----x--- bit 3 */#define BIT5(x)  (int)((x >> 5) & 0x1L) /* --x----- bit 5 */#define BIT6(x)  (int)((x >> 6) & 0x1L) /* -x------ bit 6 */#define BIT7(x)  (int)((x >> 7) & 0x1L) /* x------- bit 7 */#define BIT8(x) (int)((x >> 8) & 0x1L)#define BIT10(x) (int)((x >> 10) & 0x1L)#define BIT11(x) (int)((x >> 11) & 0x1L)#define BIT12(x) (int)((x >> 12) & 0x1L)#define BIT15(x) (int)((x >> 15) & 0x1L)#define BITS15_8(x) (int)((x >> 8) & 0xffL) #define BITS15_7(x) (int)((x >> 7) & 0x1ffL)#define BITS14_12(x) (int)((x >> 12) & 0x7L)#define BITS11_9(x) (int)((x >> 9) & 0x7L)  /* bits 11 through 9 */#define BITS11_8(x) (int)((x >> 8) & 0xfL)  /* bits 11 through 8 */#define BITS10_9(x) (int)((x >> 9) & 0x3L)  /* bits 10 through 9 */#define BITS10_8(x) (int)((x >> 8) & 0x7L)  /* bits 10 through 8 */#define BITS8_6(x) (int)((x >> 6) & 0x7L)   /* bits 8 through 6 */#define BITS8_3(x) (int)((x >> 3) & 0x3fL)  /* bits 8 through 3 */#define BITS7_6(x) (int)((x >> 6) & 0x3L)   /* bits 7 through 6 */#define BITS5_4(x) (int)((x >> 4) & 0x3L)   /* bits 5 through 4 */#define BITS5_3(x) (int)((x >> 3) & 0x7L)   /* bits 5 through 3 */#define BITS5_0(x) (int)(x & 0x3fL)     /* bits 5 through 0 */#define BITS4_3(x) (int)((x >> 3) & 0x3L)   /* bits 4 through 3 */#define BITS3_0(x) (int)(x & 0xfL)      /* bits 3 through 0 */#define BITS2_0(x) (int)(x & 0x7L)      /* bits 2 through 0 */#define LOW8(x) (int)(x & 0xffL)        /* low 8 bits of quantity   */#define HIOF32(x) (int)((x >> 31) & 0x1L)   /* sign bit of 32 bit quantity  */#define HI4OF16(x) (int)((x >> 12) & 0xfL)#define NCPS    8   /* Number of chars per symbol.      */#define NHEX    80  /* Maximum # chars in object per line.  */#define NLINE   33  /* Maximum # chars in mnemonic per line.*/#define FAIL    0#define LEAD    1#define NOLEAD  0#define TERM    0#define BYTE    1    /* values for size parm to eff_add */#define WORD    2#define LONG    3#define SIGNED      1 /* immediate value signed or unsigned */#define UNSIGNED    0#define NOTSIGNED   0unsigned short curinstr;    /* for saving first part of instruction                   when cur2bytes is used to read displ */unsigned short oldinstr = 0;    /* to save previous instruction for                   testing that swbeg follows jump  */unsigned short  cur2bytes;  /* for storing the results of 'get2bytes()' */static int  shownext;static long loc;        /* byte location being disassembled *//* IMPORTANT: remember that loc is incremented*//* only by the getbyte routine  */static char object[NHEX];   /* array to store object code for output*/static char mneu[NLINE];    /* array to store mnemonic code for output*/char    conv_temp[NHEX];    /* Temporary location for ascii *//* representation of operands.  */char    comp_temp[NHEX];    /* temp for calling compoff */static char size[] = {    'b','w','l'};char    *cond_codes[] = {            "t      ",  "f      ",  "hi     ",  "ls     ",            "cc     ",  "cs     ",  "ne     ",  "eq     ",            "vc     ",  "vs     ",  "pl     ",  "mi     ",            "ge     ",  "lt     ",  "gt     ",  "le     "        };char    *addregs[] = {     "%a0","%a1","%a2","%a3","%a4","%a5","%fp","%sp" };void    confused();char    *eff_add();void    bit_movep_imm(), move_byte(), move_long(), move_word(), miscell();void    addq_subq_scc_dbcc(), bcc_bsr_bra(), moveq(), or_div_sbcd(), sub_subx();void    unassigned(), cmp_eor(), and_mul_abcd_exg(), add_addx(), shft_rot();void (*code_map[16])() ={        bit_movep_imm,      /* upper nibble 0x0 */        move_byte,      /* upper nibble 0x1 */        move_long,      /* upper nibble 0x2 */        move_word,      /* upper nibble 0x3 */        miscell,        /* upper nibble 0x4 */        addq_subq_scc_dbcc,     /* upper nibble 0x5 */        bcc_bsr_bra,        /* upper nibble 0x6 */        moveq,          /* upper nibble 0x7 */        or_div_sbcd,        /* upper nibble 0x8 */        sub_subx,       /* upper nibble 0x9 */        unassigned,     /* upper nibble 0xa */        cmp_eor,        /* upper nibble 0xb */        and_mul_abcd_exg,   /* upper nibble 0xc */        add_addx,       /* upper nibble 0xd */        shft_rot,       /* upper nibble 0xe */        unassigned      /* upper nibble 0xf */};char *DisHelp[] = {    "Disassemble memory",    "{address | .} [lines]",    0,};extern int getreg();/* ELS: With the original disassembler, it attempted to recover from     a confused state by re-syncing on the next line of source.*/voidconfused(){    printf("\tDisassembler confused around 0x%lx\n",loc);    monrestart(MISC);}/* *  compoff (lng, temp) * *  This routine will compute the location to which control is to be *  transferred.  'lng' is the number indicating the jump amount *  (already in proper form, meaning masked and negated if necessary) *  and 'temp' is a character array which already has the actual *  jump amount.  The result computed here will go at the end of 'temp'. *  (This is a great routine for people that don't like to compute in *  hex arithmetic.) */voidcompoff(long lng, char *temp){    extern  long    loc;    /* from _extn.c */    lng += loc;    sprintf(temp,"%s <%lx>",temp,lng);}/* *  convert (num, temp, flag) * *  Convert the passed number to hex leaving the result in the *  supplied string array. *  If  LEAD  is specified, preceed the number with '0' or '0x' to *  indicate the base (used for information going to the mnemonic *  printout).  NOLEAD  will be used for all other printing (for *  printing the offset, object code, and the second byte in two *  byte immediates, displacements, etc.) and will assure that *  there are leading zeros. */voidconvert(num,temp,flag)unsigned int    num;char temp[];int flag;{    if (flag == NOLEAD)        sprintf(temp,"%04x",num);    if (flag == LEAD)        sprintf(temp,"0x%x",num);}/* *  get2bytes() * *  This routine will get 2 bytes, print them in the object file *  and place the result in 'cur2bytes'. * */voidget2bytes(){    uchar bytes[16], *bc;    bc = (uchar *)loc;    bytes[0] = bc[0];    bytes[1] = bc[1];    cur2bytes = *(unsigned short *)loc;    loc += 2;    convert( (cur2bytes & 0xffff), bytes, NOLEAD);    sprintf(object,"%s%s ",object, bytes);}/* *  print_dis () * *  Print the disassembled line, consisting of the object code *  and the mnemonics.  The breakpointable line number, if any, *  has already been printed, and 'object' contains the offset *  within the section for the instruction. */voidprint_dis(){    printf("%-35s%s\n",object,mneu);}/* *  prt_offset () * *  Print the offset, right justified, followed by a ':'. */voidprt_offset(){    if (shownext)        strcpy(object,"NextInst: ");    else        sprintf(object,"0x%08lx: ",loc);}intdisass(ulong at,int lines,int next){    int i;    ulong   start;    shownext = next;    if ((at == 0) && (lines == 0)) {        lines = 1;        getreg("PC",&loc);        start = loc;    }    else {        loc = at;        start = at;    }    for(i=0;i<lines;i++) {        prt_offset();        mneu[0] = '\0';        oldinstr = curinstr;        get2bytes();        /*save bytes in case eff_add changes it*/        curinstr = cur2bytes;        comp_temp[0] = '\0';        (*code_map[HI4OF16(cur2bytes)])();        /* if there was any pc rel computation                    put it at the end of assembly line */        strcat(mneu,comp_temp);        print_dis();    }    return((int)loc - start);}intDis(int argc,char *argv[]){    int lines;    ulong   at;    if (*argv[1] == '.')        getreg("PC",&at);    else        at = strtoul(argv[1],0,0);    if (argc == 3)        lines = strtol(argv[2],0,0);    else        lines = 8;    while(1) {        disass(at,lines,0);        if (More())            at = loc;        else            break;    }    return(0);}voidmove_address(){    strcat(mneu,"mova._  ");    mneu[5] = BIT12(cur2bytes) ? 'w' : 'l';    strcat(mneu,eff_add(BITS5_3(cur2bytes),BITS2_0(cur2bytes),        BIT12(cur2bytes) ? WORD : LONG,NOTSIGNED));    sprintf(mneu,"%s,%s",mneu,addregs[BITS11_9(curinstr)]);}voidbit_movep_imm(){    static char *misc_ops[4] = {                    "btst    ",                    "bchg    ",                    "bclr    ",                    "bset    "                    };    if (BIT8(cur2bytes)) {        if (BITS5_3(cur2bytes) == 1) {  /* movep */            strcat(mneu,"movp._  ");            mneu[5] = BIT6(cur2bytes) ? 'l' : 'w';            if (BIT7(cur2bytes))                sprintf(mneu,"%s%%d%d,%s",mneu,                    BITS11_9(curinstr),                    eff_add(5,BITS2_0(cur2bytes),                    NULL,NULL));                else                sprintf(mneu,"%s%s,%%d%d",mneu,                    eff_add(5,BITS2_0(cur2bytes),NULL,                    NULL), BITS11_9(curinstr));        }        else {  /* dynamic bit */            strcat(mneu,misc_ops[BITS7_6(cur2bytes)]);            sprintf(mneu,"%s%%d%d,%s",mneu,BITS11_9(curinstr),                eff_add(BITS5_3(cur2bytes),BITS2_0(cur2bytes),                NULL,NULL));        }        return;    } /* end if (BIT8(cur2bytes)) */    switch(BITS11_9(cur2bytes)) {        char add_temp[16];    case 0:        if (BITS7_6(cur2bytes) == 3)            confused();        strcat(mneu,"ori._   ");        mneu[4] = size[BITS7_6(cur2bytes)];        strcat(mneu,eff_add(7,4,BITS7_6(cur2bytes) + 1,UNSIGNED));        strcat(mneu,",");        if (BITS5_0(curinstr) == 074) {            if (BITS7_6(curinstr) == 0)                strcat(mneu,"%cc");            else if (BITS7_6(curinstr) == 1)                strcat(mneu,"%sr");                else                confused();        }        else            strcat(mneu,eff_add(BITS5_3(curinstr),                BITS2_0(curinstr),NULL,NULL));        return;    case 1:        if (BITS7_6(cur2bytes) == 3)            confused();        strcat(mneu,"andi._  ");        mneu[5] = size[BITS7_6(cur2bytes)];        strcat(mneu,eff_add(7,4,BITS7_6(cur2bytes) + 1,UNSIGNED));        strcat(mneu,",");        if (BITS5_0(curinstr) == 074) {            if (BITS7_6(curinstr) == 0)                strcat(mneu,"%cc");            else if (BITS7_6(curinstr) == 1)                strcat(mneu,"%sr");                else                confused();        }        else            strcat(mneu,eff_add(BITS5_3(curinstr),                BITS2_0(curinstr),NULL,NULL));        return;    case 2:        if ((BITS7_6(cur2bytes) == 3) || (BITS5_0(cur2bytes) == 074))            confused();        strcat(mneu,"subi._  ");        mneu[5] = size[BITS7_6(cur2bytes)];        strcat(mneu,eff_add(7,4,BITS7_6(cur2bytes) + 1,UNSIGNED));        strcat(mneu,",");        strcat(mneu,eff_add(BITS5_3(curinstr),BITS2_0(curinstr),            NULL,NULL));        return;    case 3:        if ((BITS7_6(cur2bytes) == 3) || (BITS5_0(cur2bytes) == 074))            confused();        strcat(mneu,"addi._  ");        mneu[5] = size[BITS7_6(cur2bytes)];        strcat(mneu,eff_add(7,4,BITS7_6(cur2bytes) + 1,UNSIGNED));        strcat(mneu,",");        strcat(mneu,eff_add(BITS5_3(curinstr),BITS2_0(curinstr),            NULL,NULL));        return;    case 4:        strcat(mneu,misc_ops[BITS7_6(cur2bytes)]);        strcat(mneu,eff_add(7,4,(BITS7_6(cur2bytes) ==1) ?            BYTE : WORD,UNSIGNED));        strcat(mneu,",");        strcat(mneu,eff_add(BITS5_3(curinstr),            BITS2_0(curinstr),NULL,NULL));        return;    case 5:        if (BITS7_6(cur2bytes) == 3)            confused();        strcat(mneu,"eori._   ");        mneu[5] = size[BITS7_6(cur2bytes)];        strcat(mneu,eff_add(7,4,BITS7_6(cur2bytes) + 1,UNSIGNED));        strcat(mneu,",");        if (BITS5_0(curinstr) == 074) {            if (BITS7_6(curinstr) == 0)                strcat(mneu,"%cc");            else if (BITS7_6(curinstr == 1))                strcat(mneu,"%sr");                else                confused();        }        else            strcat(mneu,eff_add(BITS5_3(curinstr),                BITS2_0(curinstr),NULL,NULL));        return;    case 6:        if ((BITS7_6(cur2bytes) == 3) || (BITS5_0(cur2bytes) == 074))            confused();        strcat(mneu,"cmpi._  ");        mneu[5] = size[BITS7_6(cur2bytes)];        strcpy(add_temp,eff_add(7,4,BITS7_6(cur2bytes)+1,NOTSIGNED));        strcat(mneu,eff_add(BITS5_3(curinstr),BITS2_0(curinstr),            NULL,NULL));        strcat(mneu,",");        strcat(mneu,add_temp);        return;#ifdef M68010    case 7:        {            short osz, regtype, regnum, movsdir;            char  curea[24], rreg[6];            short ea1, eareg;            osz = BITS7_6(cur2bytes);            if (osz == 3)                confused();            ea1 = BITS5_3(cur2bytes);            eareg = BITS2_0(cur2bytes);            strcat(mneu,"movs.");            strcat(mneu,(osz==2)?("l"):( (osz==1)?("w"):("b") ));            strcat(mneu,"  ");            get2bytes();            movsdir = BIT11(cur2bytes);            regtype = BIT15(cur2bytes);            regnum  = BITS14_12(cur2bytes);            strcpy(curea,                eff_add(ea1,eareg,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -