asmdata.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 896 行 · 第 1/2 页
C
896 行
if( store_fixup( 0 ) == ERROR )
return( ERROR );
#endif
/* now actually output the data */
ptr = (char *)&data;
#if defined( _STANDALONE_ )
if( sym && Parse_Pass == PASS_1 ) {
update_sizes( sym, first, no_of_bytes );
}
if( !struct_field ) {
#endif
/* only output up to 4 bytes of offset (segment is on fixup) */
for( i = 0; i < min( no_of_bytes, 4 ); i++ ) {
AsmDataByte( *ptr );
ptr++;
}
/* leave space for segment */
for( ; i < no_of_bytes; i++ ) {
AsmDataByte( 0 );
}
#if defined( _STANDALONE_ )
} else if( the_struct != NULL ) {
Definition.curr_struct->e.structinfo->size += no_of_bytes;
update_sizes( the_struct, first, no_of_bytes );
}
#endif
// set position back to main loop worked correctly
cur_pos--;
break;
}
case T_UNARY_OPERATOR: {
int i;
int fixup_type;
int seg_off_operator_loc = 0;
asm_sym *init_sym;
char *ptr;
long data = 0;
struct asmfixup *fixup;
if( AsmBuffer[cur_pos]->value == T_OFFSET ||
AsmBuffer[cur_pos]->value == T_SEG ) {
// see asmins.h about T_SEG
if( no_of_bytes < 2 ) {
AsmError( OFFSET_TOO_SMALL );
return( ERROR );
}
}
seg_off_operator_loc = cur_pos;
#if defined( _STANDALONE_ )
i = ++cur_pos;
if( i + 2 < Token_Count ) {
if( ( AsmBuffer[i]->token == T_RES_ID )
&& ( AsmBuffer[i + 1]->token == T_RES_ID )
&& ( AsmBuffer[i + 1]->value == T_PTR ) ) {
i += 2;
}
}
if( check_override( &i ) == ERROR ) {
return( ERROR );
}
i--;
cur_pos = i;
#endif
if( cur_pos + 1 < Token_Count ) {
if( AsmBuffer[++cur_pos]->token == T_ID ) {
init_sym = AsmLookup( AsmBuffer[cur_pos]->string_ptr );
if( init_sym == NULL )
return( ERROR );
if( AsmBuffer[seg_off_operator_loc]->value == T_OFFSET ) {
if( init_sym->state == SYM_STACK ) {
AsmError( CANNOT_OFFSET_AUTO );
return( ERROR );
#if defined( _STANDALONE_ )
} else if( init_sym->state == SYM_GRP ) {
AsmError( CANNOT_OFFSET_GRP );
return( ERROR );
#endif
}
switch( no_of_bytes ) {
case 1:
AsmError( OFFSET_TOO_SMALL ); // fixme
return( ERROR );
case 2:
fixup_type = FIX_OFF16;
break;
case 4:
fixup_type = FIX_OFF32;
#if defined( _STANDALONE_ )
if( !SymIs32( init_sym ) ) {
fixup_type = FIX_OFF16;
}
#endif
break;
default:
AsmError( NOT_IMPLEMENTED );
return( ERROR );
}
} else if( AsmBuffer[seg_off_operator_loc]->value == T_SEG ) {
if( init_sym->state == SYM_STACK ) {
AsmError( CANNOT_SEG_AUTO );
}
fixup_type = FIX_SEG;
}
switch( AsmBuffer[seg_off_operator_loc]->value ) {
case T_OFFSET:
#if defined( _STANDALONE_ )
if( init_sym->state == SYM_STRUCT_FIELD ) {
data = init_sym->offset;
break;
}
#endif
case T_SEG:
#if defined( _STANDALONE_ )
find_frame( init_sym );
#endif
fixup = AddFixup( init_sym, fixup_type, OPTJ_NONE );
InsFixups[OPND1] = fixup;
if( AsmBuffer[seg_off_operator_loc]->value == T_OFFSET ) {
data += fixup->offset;
}
#if defined( _STANDALONE_ )
if( store_fixup( 0 ) == ERROR )
return( ERROR );
#endif
break;
#if defined( _STANDALONE_ )
case T_LENGTH:
data = init_sym->first_length;
break;
case T_LENGTHOF:
data = init_sym->total_length;
break;
case T_SIZE:
data = init_sym->first_size;
break;
case T_SIZEOF:
data = init_sym->total_size;
break;
#endif
default:
AsmError( SYNTAX_ERROR );
return( ERROR );
}
for( cur_pos++;
( cur_pos < Token_Count ) && ( AsmBuffer[cur_pos]->token != T_FINAL)
&& ( AsmBuffer[cur_pos]->token != T_COMMA );
cur_pos++ ) {
switch( AsmBuffer[cur_pos]->token ) {
case T_PLUS:
case T_DOT:
case T_OP_SQ_BRACKET:
break;
#if defined( _STANDALONE_ )
case T_ID:
init_sym = AsmLookup( AsmBuffer[cur_pos]->string_ptr );
data += init_sym->offset;
break;
#endif
case T_MINUS:
if( AsmBuffer[cur_pos+1]->token != T_NUM ) {
AsmError( EXPECTING_NUMBER );
return( ERROR );
}
AsmBuffer[cur_pos+1]->value *=-1;
break;
case T_NUM:
data += AsmBuffer[cur_pos]->value;
}
}
/* now actually output the data */
ptr = (char *)&data;
#if defined( _STANDALONE_ )
if( sym && Parse_Pass == PASS_1 ) {
update_sizes( sym, first, no_of_bytes );
}
if( !struct_field ) {
#endif
for( i = 0; i < no_of_bytes; i++ ) {
AsmDataByte( *ptr );
ptr++;
}
#if defined( _STANDALONE_ )
} else {
if( the_struct == NULL )
break;
Definition.curr_struct->e.structinfo->size += no_of_bytes;
update_sizes( the_struct, first, no_of_bytes );
}
#endif
} else {
AsmError( SYNTAX_ERROR );
return( ERROR );
}
}
// set position back to main loop worked correctly
cur_pos--;
// AsmError( NOT_IMPLEMENTED );
break;
}
case T_CL_BRACKET:
return( cur_pos );
default:
AsmError( EXPECTING_NUMBER );
return( ERROR );
}
}
return( cur_pos );
}
static int dup_array( asm_sym *sym, asm_sym *struct_sym, int start_pos, unsigned no_of_bytes )
/********************************************************************************************/
/*
parse array with DUP operator;
*/
{
int cur_pos = start_pos;
int returned_pos;
int count;
#if defined( _STANDALONE_ )
bool was_first;
#endif
ExpandTheWorld( start_pos, FALSE, TRUE );
while( cur_pos + 2 < Token_Count ) {
if(( AsmBuffer[cur_pos + 1]->token == T_RES_ID )
&& ( AsmBuffer[cur_pos + 1]->value == T_DUP )) {
if( AsmBuffer[cur_pos]->token != T_NUM ) {
AsmError( SYNTAX_ERROR );
return( ERROR );
}
count = AsmBuffer[cur_pos]->value;
cur_pos += 2;
if( AsmBuffer[cur_pos]->token != T_OP_BRACKET ) {
AsmError( SYNTAX_ERROR );
return( ERROR );
}
cur_pos++;
#if defined( _STANDALONE_ )
was_first = first;
#endif
while( count > 0 ) {
/* in case there was a "," inside the dup */
#if defined( _STANDALONE_ )
first = was_first;
#endif
returned_pos = array_element( sym, struct_sym, cur_pos, no_of_bytes );
if( returned_pos == ERROR )
return( ERROR );
count--;
}
if( AsmBuffer[returned_pos]->token != T_CL_BRACKET ) {
AsmError( BRACKET_EXPECTED );
return( ERROR );
}
} else {
returned_pos = array_element( sym, struct_sym, cur_pos, no_of_bytes );
if( returned_pos == ERROR )
return( ERROR );
if( AsmBuffer[returned_pos]->token != T_CL_BRACKET ) {
/* array_element hit T_FINAL so stop */
return( returned_pos );
}
}
if( AsmBuffer[returned_pos+1]->token != T_COMMA ) {
return( returned_pos );
}
cur_pos = returned_pos + 2;
#if defined( _STANDALONE_ )
first = FALSE;
#endif
}
return( array_element( sym, struct_sym, cur_pos, no_of_bytes ) );
}
int data_init( int sym_loc, int initializer_loc )
/***********************************************/
/*
parse data initialization assembly line;
*/
{
unsigned no_of_bytes;
memtype mem_type;
struct asm_sym *sym = NULL;
struct asm_sym *struct_sym = NULL;
#if defined( _STANDALONE_ )
uint old_offset;
char label_dir = FALSE;
struct_field = FALSE;
first = TRUE;
#endif
if( sym_loc >= 0 ) {
sym = AsmLookup( AsmBuffer[sym_loc]->string_ptr );
if( sym == NULL ) {
return( ERROR );
}
}
switch( AsmBuffer[initializer_loc]->value ) {
#if defined( _STANDALONE_ )
case T_SBYTE: // 20-Aug-92
mem_type = MT_SBYTE;
no_of_bytes = BYTE_1;
break;
case T_SWORD: // 20-Aug-92
mem_type = MT_SWORD;
no_of_bytes = BYTE_2;
break;
case T_SDWORD: // 20-Aug-92
mem_type = MT_SDWORD;
no_of_bytes = BYTE_4;
break;
case T_DQ:
case T_QWORD:
mem_type = MT_QWORD;
no_of_bytes = BYTE_8;
break;
case T_DT:
case T_TBYTE: // 20-Aug-92
mem_type = MT_TBYTE;
no_of_bytes = BYTE_10;
break;
case T_OWORD:
mem_type = MT_OWORD;
no_of_bytes = BYTE_16;
break;
case T_STRUC:
case T_STRUCT:
mem_type = MT_STRUCT;
struct_sym = AsmLookup( AsmBuffer[initializer_loc]->string_ptr );
no_of_bytes = GetStructSize( struct_sym );
break;
#endif
case T_DB:
case T_BYTE:
mem_type = MT_BYTE;
no_of_bytes = BYTE_1;
break;
case T_DW:
case T_WORD:
mem_type = MT_WORD;
no_of_bytes = BYTE_2;
break;
case T_DD:
case T_DWORD:
mem_type = MT_DWORD;
no_of_bytes = BYTE_4;
break;
case T_DF: // 20-Aug-92
case T_FWORD:
case T_DP:
case T_PWORD:
mem_type = MT_FWORD;
no_of_bytes = BYTE_6;
break;
default:
AsmError( INVALID_LABEL_DEFINITION );
return( ERROR );
}
if( AsmBuffer[ initializer_loc + 1 ]->token == T_FINAL ) {
AsmError( SYNTAX_ERROR );
return( ERROR );
}
#if defined( _STANDALONE_ )
if( sym_loc >= 0 && AsmBuffer[ sym_loc ]->value == T_LABEL ) {
label_dir = TRUE;
sym_loc--;
}
if( sym_loc < 0 ) {
if( Definition.struct_depth != 0 ) {
if( Parse_Pass == PASS_1 ) {
AddFieldToStruct( initializer_loc );
struct_field = TRUE;
} else {
return( NOT_ERROR );
}
}
}
#endif
if( More_Array_Element == TRUE ) {
More_Array_Element = FALSE;
} else if( sym_loc >= 0 ) {
#if defined( _STANDALONE_ )
/* defining a field in a structure */
if( Definition.struct_depth != 0 ) {
if( Parse_Pass == PASS_1 ) {
sym->offset = AddFieldToStruct( initializer_loc );
struct_field = TRUE;
sym->state = SYM_STRUCT_FIELD;
sym->mem_type = mem_type;
if( dup_array( sym, NULL, initializer_loc + 1, no_of_bytes ) == ERROR ) {
return( ERROR );
}
}
return( NOT_ERROR );
}
if( Parse_Pass == PASS_1 ) {
if( sym->state != SYM_UNDEFINED ) {
// redefine label
AsmError( SYMBOL_ALREADY_DEFINED );
return( ERROR );
}
} else {
old_offset = sym->offset;
}
GetSymInfo( sym );
if( Parse_Pass != PASS_1 && sym->offset != old_offset ) {
PhaseError = TRUE;
}
#else
if( sym->state != SYM_UNDEFINED ) {
// redefine label
AsmError( SYMBOL_ALREADY_DEFINED );
return( ERROR );
}
#endif
sym->state = SYM_INTERNAL;
sym->mem_type = mem_type;
BackPatch( sym );
}
#if defined( _STANDALONE_ )
if( label_dir )
return( NOT_ERROR );
#endif
if( dup_array( sym, struct_sym, initializer_loc + 1, no_of_bytes ) == ERROR ) {
return( ERROR );
}
return( NOT_ERROR );
}
int NextArrayElement( void )
{
if( More_Array_Element ) {
More_Array_Element = FALSE;
return( dup_array( NULL, NULL, 0, Last_Element_Size ) );
} else {
return( EMPTY );
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?