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 + -
显示快捷键?