asmdata.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 896 行 · 第 1/2 页
C
896 行
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: data directive DB,DW,DD,... and structure processing
*
****************************************************************************/
#include "asmglob.h"
#include "asmdefs.h"
#include "asmsym.h"
#include "asmins.h"
#include "asmexpnd.h"
#include "tbyte.h"
#include "asmfixup.h"
#if defined( _STANDALONE_ )
#include "directiv.h"
#endif
#ifndef min
#define min(x,y) (((x) < (y)) ? (x) : (y))
#endif
/* structure stuff from asmstruct */
extern int InitializeStructure( asm_sym *, asm_sym *, int );
extern int AddFieldToStruct( int );
extern int GetStructSize( asm_sym * );
#if defined( _STANDALONE_ )
extern int ChangeCurrentLocation( bool, int_32, bool );
extern int SymIs32( struct asm_sym *sym );
/* static globals */
/* is this data element a field in a structure definition? */
static bool struct_field;
/* is this the first initializer for this field? */
static bool first;
#endif
static int dup_array( asm_sym *sym, asm_sym *struct_sym, int start_pos, unsigned no_of_bytes );
static bool More_Array_Element = FALSE;
static unsigned Last_Element_Size;
/* data initialization stuff */
static void little_endian( char *string, unsigned no_of_bytes )
/*************************************************************/
/* convert a string into little endian format - ( LSB 1st, LSW 1st ... etc ) */
{
if( no_of_bytes >= 2 ) {
strrev( string );
}
return;
}
static void output_float( char index, unsigned no_of_bytes, char negative )
/*************************************************************************/
{
double double_value;
float float_value;
char *char_ptr;
uint_8 count;
TB_LD tbyte;
if( no_of_bytes == BYTE_10 ) {
char_ptr = (char *)strtotb( AsmBuffer[index]->string_ptr, &tbyte, negative );
} else {
double_value = strtod( AsmBuffer[index]->string_ptr, NULL );
if( negative )
double_value *= -1;
switch( no_of_bytes ) {
case BYTE_1:
case BYTE_2:
#if defined( _STANDALONE_ )
AsmWarn( 4, FLOAT_OPERAND );
#endif
char_ptr = (char *)&AsmBuffer[index]->value;
break;
case BYTE_4:
float_value = double_value;
char_ptr = (char *)&float_value;
break;
case BYTE_8:
char_ptr = (char *)&double_value;
break;
}
}
count = 0;
while( count < no_of_bytes ) {
AsmDataByte( *char_ptr );
char_ptr++;
count++;
}
return;
}
#if defined( _STANDALONE_ )
static void update_sizes( asm_sym *sym, bool first, unsigned no_of_bytes )
/************************************************************************/
{
sym->total_length++;
sym->total_size += no_of_bytes;
if( first ) {
sym->first_length++;
sym->first_size += no_of_bytes;
}
}
#endif
static int array_element( asm_sym *sym, asm_sym *struct_sym, int start_pos, unsigned no_of_bytes )
/************************************************************************************************/
/*
- parse an array and initialize the number;
- call by dup_array() only;
*/
{
int cur_pos = start_pos;
char count;
char *char_ptr;
char negative = FALSE;
#if defined( _STANDALONE_ )
asm_sym *the_struct;
int tmp;
the_struct = (asm_sym*)Definition.curr_struct;
if( sym != NULL ) {
sym->count++;
}
#endif
for( cur_pos = start_pos;
( cur_pos < Token_Count ) && ( AsmBuffer[cur_pos]->token != T_FINAL );
cur_pos++ ) {
#if defined( _STANDALONE_ )
if( AsmBuffer[cur_pos]->token == T_RES_ID )
continue;
tmp = cur_pos;
if( check_override( &tmp ) == ERROR )
return( ERROR );
cur_pos = tmp;
#endif
if(( cur_pos == Token_Count - 1 )
&& ( AsmBuffer[cur_pos]->token == T_CL_BRACKET ))
break;
switch( AsmBuffer[cur_pos]->token ) {
case T_QUESTION_MARK:
if( cur_pos != start_pos ) {
if( AsmBuffer[cur_pos - 1]->token != T_COMMA ) {
AsmError( EXPECTING_COMMA );
return( ERROR );
}
}
#if defined( _STANDALONE_ )
if( !struct_field ) {
ChangeCurrentLocation( TRUE, no_of_bytes,
( ( CurrSeg != NULL ) && SEGISCODE( CurrSeg ) ) );
} else {
Definition.curr_struct->e.structinfo->size += no_of_bytes;
the_struct->total_size += no_of_bytes;
the_struct->total_length++;
the_struct->first_size += no_of_bytes;
the_struct->first_length++;
}
if( sym && Parse_Pass == PASS_1 ) {
update_sizes( sym, first, no_of_bytes );
}
#else
count = 0;
while( count < no_of_bytes ) {
AsmDataByte( 0 );
count++;
}
#endif
break;
case T_MINUS:
switch( AsmBuffer[cur_pos+1]->token ) {
case T_NUM:
AsmBuffer[cur_pos+1]->value *= -1;
AsmBuffer[cur_pos]->token = T_PLUS;
break;
case T_FLOAT:
negative = TRUE;
break;
default:
AsmError( EXPECTING_NUMBER );
return( ERROR );
}
break;
case T_PLUS:
case T_DOT:
break; // go around again
case T_NUM:
case T_FLOAT:
if( AsmBuffer[cur_pos+1]->token == T_RES_ID &&
AsmBuffer[cur_pos+1]->value == T_DUP ) {
cur_pos = dup_array( sym, struct_sym, cur_pos, no_of_bytes );
if( cur_pos == ERROR )
return( ERROR );
break;
}
if( cur_pos != start_pos ) {
switch( AsmBuffer[cur_pos - 1]->token ) {
case T_COMMA:
break;
case T_PLUS:
case T_MINUS:
if( AsmBuffer[cur_pos - 2]->token == T_COMMA )
break;
if( cur_pos - 1 == start_pos )
break;
default:
AsmError( EXPECTING_COMMA );
return( ERROR );
}
}
if( AsmBuffer[cur_pos]->token == T_FLOAT ) {
output_float( cur_pos, no_of_bytes, negative );
negative = FALSE;
break;
}
count = 0;
char_ptr = AsmBuffer[cur_pos]->bytes;
#if defined( _STANDALONE_ )
if( sym && Parse_Pass == PASS_1 ) {
update_sizes( sym, first, no_of_bytes );
}
if( !struct_field ) {
#endif
while( count < no_of_bytes ) {
AsmDataByte( *(char_ptr++) );
count++;
}
#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
break;
case T_COMMA:
#if defined( _STANDALONE_ )
first = FALSE;
#endif
if( cur_pos != start_pos ) {
if( AsmBuffer[cur_pos - 1]->token == T_COMMA ) {
AsmError( EXPECTING_NUMBER );
return( ERROR );
/********SHOULD WE DO IT THIS WAY?*********
for( count = 0; count < no_of_bytes; count++ ) {
AsmDataByte( 0x00 );
}
******************************************/
}
} else {
AsmError( EXPECTING_NUMBER );
return( ERROR );
}
if( cur_pos == ( Token_Count - 1 ) ) {
More_Array_Element = TRUE;
Last_Element_Size = no_of_bytes;
}
break;
case T_STRING:
#if defined( _STANDALONE_ )
if( struct_sym != NULL ) {
InitializeStructure( sym, struct_sym, cur_pos );
break;
}
#endif
if( no_of_bytes != 1 ) {
if( AsmBuffer[cur_pos]->value > no_of_bytes ) {
AsmError( INITIALIZER_OUT_OF_RANGE );
return( ERROR );
}
}
count = 0;
char_ptr = AsmBuffer[cur_pos]->string_ptr;
/* anything bigger than a byte must be stored in little-endian
* format -- LSB first */
little_endian( char_ptr, no_of_bytes );
#if defined( _STANDALONE_ )
if( no_of_bytes == 1 && struct_field ) {
no_of_bytes = AsmBuffer[cur_pos]->value;
}
if( sym && Parse_Pass == PASS_1 ) {
update_sizes( sym, first, no_of_bytes );
}
if( !struct_field ) {
#endif
while( count < AsmBuffer[cur_pos]->value ) {
AsmDataByte( *char_ptr );
char_ptr++;
count++;
}
while( count < no_of_bytes ) {
AsmDataByte( 0 );
char_ptr++;
count++;
}
#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
break;
case T_ID: {
int i;
int fixup_type;
asm_sym *init_sym;
char *ptr;
long data = 0;
struct asmfixup *fixup;
/* temporary test .. if this works, combine code for id & resid */
#if defined( _STANDALONE_ )
i = ++cur_pos;
if( check_override( &i ) == ERROR ) {
return( ERROR );
}
i--;
cur_pos = i;
switch( ExpandSymbol( i, FALSE ) ) {
case ERROR:
return( ERROR );
case STRING_EXPANDED:
continue;
}
#endif
init_sym = AsmLookup( AsmBuffer[cur_pos]->string_ptr );
if( init_sym == NULL )
return( ERROR );
#if defined( _STANDALONE_ )
switch( init_sym->state ) {
case SYM_STRUCT_FIELD:
AsmBuffer[cur_pos]->token = T_NUM;
AsmBuffer[cur_pos]->value = init_sym->offset;
continue;
case SYM_GRP:
case SYM_SEG:
fixup_type = FIX_SEG;
break;
default:
#endif
switch( no_of_bytes ) {
case 1:
AsmError( OFFSET_TOO_SMALL ); // fixme
return( ERROR );
case 2:
fixup_type = FIX_OFF16;
break;
case 4:
if( Code->use32 ) {
fixup_type = FIX_OFF32;
} else {
fixup_type = FIX_PTR16;
}
break;
case 6:
// fixme -- this needs work .... check USE_32, etc
fixup_type = FIX_PTR32;
Code->info.opnd_type[OPND1] = OP_J48;
break;
default:
AsmError( NOT_IMPLEMENTED );
return( ERROR );
}
#if defined( _STANDALONE_ )
/* switch( init_sym->state ) from above */
}
find_frame( init_sym );
#endif
fixup = AddFixup( init_sym, fixup_type, OPTJ_NONE );
// if( fixup == NULL ) return( ERROR );
// fixme
InsFixups[OPND1] = fixup;
data += fixup->offset;
for( cur_pos++;
( cur_pos < Token_Count ) && ( AsmBuffer[cur_pos]->token != T_FINAL )
&& ( AsmBuffer[cur_pos]->token != T_COMMA )
&& ( AsmBuffer[cur_pos]->token != T_CL_BRACKET );
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;
}
}
#if defined( _STANDALONE_ )
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?