obj2asm.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 575 行 · 第 1/2 页

C
575
字号
#endif
                is_data = TRUE;
            } else {
#ifdef __PCODE__
                in_pcode = 0;
do_code:
#endif
                DoCode( &curr_ins, Segment->use_32 );
            }
            fix = NULL;
        }
        if( Pass == 2 ) {
            if( !is_data && fix == NULL && CurrIns.pref & PREF_FWAIT ) {
                if( CurrIns.opcode == I_NOP ) {
                    CurrIns.opcode = I_WAIT;
                } else if( !(CurrIns.pref & FP_INS) ) {
                    EmitWait();  /* emit WAIT instruction */
                }
            }
            FormatLine( fix, GetLabel(), is_data, in_pcode );
        }
        FreeSymTranslations();
    }
}


static  void  GetBytes( uint size )
/*********************************/
{
    while( size != 0 ) {
        GetDataByte();
        --size;
    }
}


static  void  DecodeData()
/************************/

{
    fixup               *fix;
    char                *label;
    uint_32             next_fix;
    uint_32             next_label;
    uint_32             next_stop;
    uint_32             curr_size;

    Repeats = 0;
    next_fix = GetNextFix();
    next_label = GetNextLabel();
    do {
        InsAddr = GetOffset();
        DataBytes = 0;
        fix = NULL;
        label = NULL;
        if( next_label == InsAddr ) {
            label = FormSym( Segment->last_export->name );
            Segment->last_export->dumped = TRUE;
            Segment->last_export = Segment->last_export->next_exp;
            next_label = GetNextLabel();
        }
        if( next_fix == InsAddr ) {
            fix = Segment->last_fix;
            SwallowFix( fix );
            curr_size = DataBytes;
            FindLabel( BAD_OFFSET, fix->imp_address, fix->target );
            Segment->last_fix = Segment->last_fix->next_fix;
            next_fix = GetNextFix();
            EmitData( label, fix );
        } else {
            next_stop = Segment->size;
            if( next_label < next_stop ) next_stop = next_label;
            if( next_fix   < next_stop ) next_stop = next_fix;
            curr_size = next_stop - InsAddr;
            if( curr_size > MAX_DATA_LEN ) curr_size = MAX_DATA_LEN;
            GetBytes( curr_size );
            EmitData( label, fix );
        }
        FreeSymTranslations();
    } while( !EndOfSegment() );
    if( Pass == 2 && Repeats > 1 ) {
        EmitRepeats();
    }
}


static  void  EmitData( char *label, fixup *fix )
/***********************************************/
{
    if( Pass != 2 ) {
        return;
    }
    if( Repeats != 0 ) {
        if( fix == NULL && label == NULL && DataBytes == MAX_DATA_LEN &&
               memcmp( PrevString, DataString, MAX_DATA_LEN ) == 0
#ifdef O2A
                && !DO_UNIX
#endif
               ) {
            ++Repeats;
            return;
        } else if( Repeats > 1 ) {
            EmitRepeats();
        }
    }
    FormatLine( fix, label, TRUE, 0 );
    if( DataBytes == MAX_DATA_LEN ) {     /* may repeat */
        memcpy( PrevString, DataString, MAX_DATA_LEN );
        Repeats = 1;
    } else {
        Repeats = 0;
    }
}


static  void  EmitRepeats()
/*************************/

{
    char                temp_bytes[ MAX_DATA_LEN ];
    int                 curr_bytes;

    if( Repeats == 2 ) {        /* line repeats only 1 time */
        InsAddr -= MAX_DATA_LEN;
        memcpy( temp_bytes, DataString, MAX_DATA_LEN );
        memcpy( DataString, PrevString, MAX_DATA_LEN );
        Repeats = 0;
        curr_bytes = DataBytes;
        DataBytes = MAX_DATA_LEN;
        FormatLine( NULL, NULL, TRUE, 0 );
        DataBytes = curr_bytes;
        InsAddr += MAX_DATA_LEN;
        memcpy( DataString, temp_bytes, MAX_DATA_LEN );
    } else {
        EmitDups();
    }
}


static  int  EmitWait()
/*********************/

{
    int                 old_size;
    int                 old_num_oper;
    int                 old_opcode;
    int                 i;

    if( CurrIns.opcode == I_NULL ) {
        CurrIns.opcode = I_WAIT;
    } else {
        old_size = CurrIns.ins_size;
        old_num_oper = CurrIns.num_oper;
        old_opcode = CurrIns.opcode;
        CurrIns.ins_size = 1;
        CurrIns.num_oper = 0;
        CurrIns.opcode = I_WAIT;
        DataBytes = 1;
        FormatLine( NULL, GetLabel(), FALSE, 0 );
        ++InsAddr;
        CurrIns.pref &= ~PREF_FWAIT;
        CurrIns.ins_size = old_size - 1;
        CurrIns.num_oper = old_num_oper;
        CurrIns.opcode = old_opcode;
        i = old_num_oper;
        while( --i >= 0 ) {
            --(CurrIns.op[ i ].offset);
        }
        DataBytes = CurrIns.ins_size;
        for( i = 0; i < DataBytes; ++i ) {
            DataString[ i ] = DataString[ i + 1 ];
        }
    }
    return( CurrIns.ins_size );
}


static  scan_table  *InScanTable()
/********************************/

{
    scan_table          *table;

    table = Segment->scan_tabs;
    while( table != NULL ) {
        if( InsAddr >= table->starts && InsAddr < table->ends ) {   /* open at end */
            break;
        }
        table = table->next;
    }
    return( table );
}


static  uint_32 GetNextFix()
/**************************/

{
    if( Segment->last_fix != NULL ) {
        return( Segment->last_fix->address );
    } else {
        return( ~(uint_32)0 );
    }
}


static  void  SkipHiddenLabels()
/******************************/

{
    export_sym      *exp;

    while( Segment->last_export != NULL ) {
        exp = Segment->last_export;
        if( !exp->hidden ) return;
        exp->dumped = TRUE;     //  pretend that it's dumped
        Segment->last_export = exp->next_exp;
    }
}


static  uint_32 GetNextLabel()
/****************************/

{
    if( UseORL ) SkipHiddenLabels();
    if( Segment->last_export != NULL ) {
        return( Segment->last_export->address );
    } else {
        return( ~(uint_32)0 );
    }
}


static  bool    LabelIn( bool exact )
/***********************************/

{
    export_sym      *exp;

    exp = Segment->last_export;
    while( exp != NULL && exp->dumped ) {
        exp = exp->next_exp;
    }
    if( exp == NULL ) return( FALSE );
    if( exp->address >= InsAddr+DataBytes ) return( FALSE );
    if( exact ) return( exp->address == InsAddr );
    return( exp->address > InsAddr );
}


extern  bool    LabelInInstr()
/****************************/
{
    return( LabelIn( FALSE ) );
}


extern  bool    LabelOnInstr()
/****************************/
{
    return( LabelIn( TRUE ) );
}


extern char  *GetLabel( void )
/****************************/

{
    export_sym          *sym;

    if( UseORL ) SkipHiddenLabels();
    while( Segment->last_export != NULL ) {
        sym = Segment->last_export;
        if( sym->address > InsAddr ) {
            return( NULL );
        }
        Segment->last_export = sym->next_exp;
        if( UseORL ) SkipHiddenLabels();
        if( sym->address == InsAddr ) {
            sym->dumped = TRUE;     /* label has been used */
            return( FormSym( sym->name ) );
        }
    }
    return( NULL );
}

⌨️ 快捷键说明

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