posndir.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 188 行

C
188
字号
/****************************************************************************
*
*                            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:  WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
*               DESCRIBE IT HERE!
*
****************************************************************************/


#include "asmglob.h"

#include "asmins.h"
#include "asmdefs.h"
#include "directiv.h"

#include "myassert.h"

typedef unsigned char   byte;

static byte NopList16[] = {
    2,                  /* objlen of first NOP pattern */
    0x89, 0xc0,         /* MOV AX,AX */
    0xfc                /* CLD */
};

static byte NopList32[] = {
    6,
    0x8d,0x80,0x00,0x00,0x00,0x00,  // lea     eax,+00000000H[eax]
    0x8d,0x40,0x00,                 // lea     eax,+00H[eax]
    0x8b,0xc9,                      // mov     ecx,ecx
    0x8d,0x44,0x20,0x00,            // lea     eax,+00H[eax+no_index_reg]
    0x8d,0x40,0x00,                 // lea     eax,+00H[eax]
    0x8b,0xc0,                      // mov     eax,eax
    0x90                            // nop
};

static byte *NopLists[] = { NopList16, NopList32 };

int ChangeCurrentLocation( bool relative, int_32 value, bool select_data )
/************************************************************************/
{
    if( CurrSeg == NULL )
        return( ERROR );
    if( relative ) {
        value += GetCurrAddr();
    }
    FlushCurrSeg( );
    if( select_data )
        OutSelect( TRUE );
    CurrSeg->seg->e.seginfo->current_loc = value;
    CurrSeg->seg->e.seginfo->start_loc = value;

    if( CurrSeg->seg->e.seginfo->current_loc >=
        CurrSeg->seg->e.seginfo->segrec->d.segdef.seg_length ) {
        CurrSeg->seg->e.seginfo->segrec->d.segdef.seg_length = CurrSeg->seg->e.seginfo->current_loc;
    }

    return( NOT_ERROR );
}

int OrgDirective( int i )
/***********************/
{
    struct asm_sym  *sym;
    int_32          value = 0;

    if( AsmBuffer[i+1]->token == T_NUM ) {
        return( ChangeCurrentLocation( FALSE, AsmBuffer[i+1]->value, FALSE ) );
    } else if( AsmBuffer[i+1]->token == T_ID ) {
        sym = AsmLookup( AsmBuffer[i+1]->string_ptr );
        if( AsmBuffer[i+2]->token == T_OP_SQ_BRACKET &&
            AsmBuffer[i+3]->token == T_NUM ) {
            value = AsmBuffer[i+3]->value;
        }
        return( ChangeCurrentLocation( FALSE, sym->offset + value, FALSE ) );
    }
    AsmError( EXPECTING_NUMBER );
    return( ERROR );
}

static void fill_in_objfile_space( uint size )
/********************************************/
{
    int i;
    int nop_type;

    /* first decide whether to output nulls or nops - is it a code seg? */
    if( ! SEGISCODE( CurrSeg ) ) {
        /* just output nulls */
        for( i = 0; i < size; i++ ) {
            AsmByte( 0x00 );
        }
    } else {
        /* output appropriate NOP type instructions to fill in the gap */
        /**/ myassert( Use32 == 0 || Use32 == 1 );

        while( size > NopLists[Use32][0] ) {
            for( i = 1; i <= NopLists[Use32][0]; i++ ) {
                AsmByte( NopLists[Use32][i] );
            }
            size -= NopLists[Use32][0];
        }
        if( size == 0 ) return;

        i=1; /* here i is the index into the NOP table */
        for( nop_type = NopLists[Use32][0]; nop_type > size ; nop_type-- ) {
            i+=nop_type;
        }
        /* i now is the index of the 1st part of the NOP that we want */
        for( ; nop_type > 0; nop_type--,i++ ) {
            AsmByte( NopLists[Use32][i] );
        }
    }
}

int AlignDirective( uint_16 directive, int i )
/********************************************/
{
    int_32 align_val;
    int seg_align;

    switch( directive ) {
    case T_ALIGN:
        if( AsmBuffer[i+1]->token == T_NUM ) {
            int power;

            align_val = AsmBuffer[i+1]->value;
            /* check that the parm is a power of 2 */
            for( power = 1; power < align_val; power <<= 1 );
            if( power != align_val ) {
                AsmError( POWER_OF_2 );
                return( ERROR );
            }
        } else {
            if( Token_Count == i + 1 ) {
                align_val = GetCurrSegAlign();
            } else {
                AsmError( EXPECTING_NUMBER );
                return( ERROR );
            }
        }
        break;
    case T_EVEN:
        align_val = 2;
        break;
    }
    seg_align = GetCurrSegAlign(); // # of bytes
    if( seg_align <= 0 ) {
        AsmError( NO_SEGMENT_OPENED );
        return( ERROR );
    }
    if( align_val > seg_align ) {
        AsmWarn( 1, ALIGN_TOO_HIGH );
        return( ERROR );
    }
    /* find out how many bytes past alignment we are & add the remainder */
    //store temp. value
    seg_align = GetCurrAddr() % align_val;
    if( seg_align ) {
        align_val -= seg_align;
        fill_in_objfile_space( align_val );
    }
    return( NOT_ERROR );
}

⌨️ 快捷键说明

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