⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 assemble.c

📁 nasm的全套源代码,有些我做了些修改,以方便您更方便更容易调试成功,方便学习做编译器
💻 C
📖 第 1 页 / 共 5 页
字号:
    /*
     * Check template is okay at the set cpu level
     */
    if ((itemp->flags & IF_PLEVEL) > cpu)
        return 3;

    /*
     * Check if special handling needed for Jumps
     */
    if ((unsigned char)(itemp->code[0]) >= 0370)
        return 99;

    return ret;
}

static ea *process_ea(operand * input, ea * output, int addrbits,
                      int rfield, int forw_ref)
{
    if (!(REGISTER & ~input->type)) {   /* it's a single register */
        static int regs[] = {
            R_AL, R_CL, R_DL, R_BL, R_AH, R_CH, R_DH, R_BH,
            R_AX, R_CX, R_DX, R_BX, R_SP, R_BP, R_SI, R_DI,
            R_EAX, R_ECX, R_EDX, R_EBX, R_ESP, R_EBP, R_ESI, R_EDI,
            R_MM0, R_MM1, R_MM2, R_MM3, R_MM4, R_MM5, R_MM6, R_MM7,
            R_XMM0, R_XMM1, R_XMM2, R_XMM3, R_XMM4, R_XMM5, R_XMM6, R_XMM7
        };
        int i;

        for (i = 0; i < elements(regs); i++)
            if (input->basereg == regs[i])
                break;
        if (i < elements(regs)) {
            output->sib_present = FALSE;        /* no SIB necessary */
            output->bytes = 0;  /* no offset necessary either */
            output->modrm = 0xC0 | (rfield << 3) | (i & 7);
        } else
            return NULL;
    } else {                    /* it's a memory reference */
        if (input->basereg == -1
            && (input->indexreg == -1 || input->scale == 0)) {
            /* it's a pure offset */
            if (input->addr_size)
                addrbits = input->addr_size;
            output->sib_present = FALSE;
            output->bytes = (addrbits == 32 ? 4 : 2);
            output->modrm = (addrbits == 32 ? 5 : 6) | (rfield << 3);
        } else {                /* it's an indirection */
            int i = input->indexreg, b = input->basereg, s = input->scale;
            long o = input->offset, seg = input->segment;
            int hb = input->hintbase, ht = input->hinttype;
            int t;

            if (s == 0)
                i = -1;         /* make this easy, at least */

            if (i == R_EAX || i == R_EBX || i == R_ECX || i == R_EDX
                || i == R_EBP || i == R_ESP || i == R_ESI || i == R_EDI
                || b == R_EAX || b == R_EBX || b == R_ECX || b == R_EDX
                || b == R_EBP || b == R_ESP || b == R_ESI || b == R_EDI) {
                /* it must be a 32-bit memory reference. Firstly we have
                 * to check that all registers involved are type Exx. */
                if (i != -1 && i != R_EAX && i != R_EBX && i != R_ECX
                    && i != R_EDX && i != R_EBP && i != R_ESP && i != R_ESI
                    && i != R_EDI)
                    return NULL;
                if (b != -1 && b != R_EAX && b != R_EBX && b != R_ECX
                    && b != R_EDX && b != R_EBP && b != R_ESP && b != R_ESI
                    && b != R_EDI)
                    return NULL;

                /* While we're here, ensure the user didn't specify WORD. */
                if (input->addr_size == 16)
                    return NULL;

                /* now reorganise base/index */
                if (s == 1 && b != i && b != -1 && i != -1 &&
                    ((hb == b && ht == EAH_NOTBASE)
                     || (hb == i && ht == EAH_MAKEBASE)))
                    t = b, b = i, i = t;        /* swap if hints say so */
                if (b == i)     /* convert EAX+2*EAX to 3*EAX */
                    b = -1, s++;
                if (b == -1 && s == 1 && !(hb == i && ht == EAH_NOTBASE))
                    b = i, i = -1;      /* make single reg base, unless hint */
                if (((s == 2 && i != R_ESP
                      && !(input->eaflags & EAF_TIMESTWO)) || s == 3
                     || s == 5 || s == 9) && b == -1)
                    b = i, s--; /* convert 3*EAX to EAX+2*EAX */
                if (i == -1 && b != R_ESP
                    && (input->eaflags & EAF_TIMESTWO))
                    i = b, b = -1, s = 1;
                /* convert [NOSPLIT EAX] to sib format with 0x0 displacement */
                if (s == 1 && i == R_ESP)       /* swap ESP into base if scale is 1 */
                    i = b, b = R_ESP;
                if (i == R_ESP
                    || (s != 1 && s != 2 && s != 4 && s != 8 && i != -1))
                    return NULL;        /* wrong, for various reasons */

                if (i == -1 && b != R_ESP) {    /* no SIB needed */
                    int mod, rm;
                    switch (b) {
                    case R_EAX:
                        rm = 0;
                        break;
                    case R_ECX:
                        rm = 1;
                        break;
                    case R_EDX:
                        rm = 2;
                        break;
                    case R_EBX:
                        rm = 3;
                        break;
                    case R_EBP:
                        rm = 5;
                        break;
                    case R_ESI:
                        rm = 6;
                        break;
                    case R_EDI:
                        rm = 7;
                        break;
                    case -1:
                        rm = 5;
                        break;
                    default:   /* should never happen */
                        return NULL;
                    }
                    if (b == -1 || (b != R_EBP && o == 0 &&
                                    seg == NO_SEG && !forw_ref &&
                                    !(input->eaflags &
                                      (EAF_BYTEOFFS | EAF_WORDOFFS))))
                        mod = 0;
                    else if (input->eaflags & EAF_BYTEOFFS ||
                             (o >= -128 && o <= 127 && seg == NO_SEG
                              && !forw_ref
                              && !(input->eaflags & EAF_WORDOFFS))) {
                        mod = 1;
                    } else
                        mod = 2;

                    output->sib_present = FALSE;
                    output->bytes = (b == -1 || mod == 2 ? 4 : mod);
                    output->modrm = (mod << 6) | (rfield << 3) | rm;
                } else {        /* we need a SIB */
                    int mod, scale, index, base;

                    switch (b) {
                    case R_EAX:
                        base = 0;
                        break;
                    case R_ECX:
                        base = 1;
                        break;
                    case R_EDX:
                        base = 2;
                        break;
                    case R_EBX:
                        base = 3;
                        break;
                    case R_ESP:
                        base = 4;
                        break;
                    case R_EBP:
                    case -1:
                        base = 5;
                        break;
                    case R_ESI:
                        base = 6;
                        break;
                    case R_EDI:
                        base = 7;
                        break;
                    default:   /* then what the smeg is it? */
                        return NULL;    /* panic */
                    }

                    switch (i) {
                    case R_EAX:
                        index = 0;
                        break;
                    case R_ECX:
                        index = 1;
                        break;
                    case R_EDX:
                        index = 2;
                        break;
                    case R_EBX:
                        index = 3;
                        break;
                    case -1:
                        index = 4;
                        break;
                    case R_EBP:
                        index = 5;
                        break;
                    case R_ESI:
                        index = 6;
                        break;
                    case R_EDI:
                        index = 7;
                        break;
                    default:   /* then what the smeg is it? */
                        return NULL;    /* panic */
                    }

                    if (i == -1)
                        s = 1;
                    switch (s) {
                    case 1:
                        scale = 0;
                        break;
                    case 2:
                        scale = 1;
                        break;
                    case 4:
                        scale = 2;
                        break;
                    case 8:
                        scale = 3;
                        break;
                    default:   /* then what the smeg is it? */
                        return NULL;    /* panic */
                    }

                    if (b == -1 || (b != R_EBP && o == 0 &&
                                    seg == NO_SEG && !forw_ref &&
                                    !(input->eaflags &
                                      (EAF_BYTEOFFS | EAF_WORDOFFS))))
                        mod = 0;
                    else if (input->eaflags & EAF_BYTEOFFS ||
                             (o >= -128 && o <= 127 && seg == NO_SEG
                              && !forw_ref
                              && !(input->eaflags & EAF_WORDOFFS)))
                        mod = 1;
                    else
                        mod = 2;

                    output->sib_present = TRUE;
                    output->bytes = (b == -1 || mod == 2 ? 4 : mod);
                    output->modrm = (mod << 6) | (rfield << 3) | 4;
                    output->sib = (scale << 6) | (index << 3) | base;
                }
            } else {            /* it's 16-bit */
                int mod, rm;

                /* check all registers are BX, BP, SI or DI */
                if ((b != -1 && b != R_BP && b != R_BX && b != R_SI
                     && b != R_DI) || (i != -1 && i != R_BP && i != R_BX
                                       && i != R_SI && i != R_DI))
                    return NULL;

                /* ensure the user didn't specify DWORD */
                if (input->addr_size == 32)
                    return NULL;

                if (s != 1 && i != -1)
                    return NULL;        /* no can do, in 16-bit EA */
                if (b == -1 && i != -1) {
                    int tmp = b;
                    b = i;
                    i = tmp;
                }               /* swap */
                if ((b == R_SI || b == R_DI) && i != -1) {
                    int tmp = b;
                    b = i;
                    i = tmp;
                }
                /* have BX/BP as base, SI/DI index */
                if (b == i)
                    return NULL;        /* shouldn't ever happen, in theory */
                if (i != -1 && b != -1 &&
                    (i == R_BP || i == R_BX || b == R_SI || b == R_DI))
                    return NULL;        /* invalid combinations */
                if (b == -1)    /* pure offset: handled above */
                    return NULL;        /* so if it gets to here, panic! */

                rm = -1;
                if (i != -1)
                    switch (i * 256 + b) {
                    case R_SI * 256 + R_BX:
                        rm = 0;
                        break;
                    case R_DI * 256 + R_BX:
                        rm = 1;
                        break;
                    case R_SI * 256 + R_BP:
                        rm = 2;
                        break;
                    case R_DI * 256 + R_BP:
                        rm = 3;
                        break;
                } else
                    switch (b) {
                    case R_SI:
                        rm = 4;
                        break;
                    case R_DI:
                        rm = 5;
                        break;
                    case R_BP:
                        rm = 6;
                        break;
                    case R_BX:
                        rm = 7;
                        break;
                    }
                if (rm == -1)   /* can't happen, in theory */
                    return NULL;        /* so panic if it does */

                if (o == 0 && seg == NO_SEG && !forw_ref && rm != 6 &&
                    !(input->eaflags & (EAF_BYTEOFFS | EAF_WORDOFFS)))
                    mod = 0;
                else if (input->eaflags & EAF_BYTEOFFS ||
                         (o >= -128 && o <= 127 && seg == NO_SEG
                          && !forw_ref
                          && !(input->eaflags & EAF_WORDOFFS)))
                    mod = 1;
                else
                    mod = 2;

                output->sib_present = FALSE;    /* no SIB - it's 16-bit */
                output->bytes = mod;    /* bytes of offset needed */
                output->modrm = (mod << 6) | (rfield << 3) | rm;
            }
        }
    }
    output->size = 1 + output->sib_present + output->bytes;
    return output;
}

static int chsize(operand * input, int addrbits)
{
    if (!(MEMORY & ~input->type)) {
        int i = input->indexreg, b = input->basereg;

        if (input->scale == 0)
            i = -1;

        if (i == -1 && b == -1) /* pure offset */
            return (input->addr_size != 0 && input->addr_size != addrbits);

        if (i == R_EAX || i == R_EBX || i == R_ECX || i == R_EDX
            || i == R_EBP || i == R_ESP || i == R_ESI || i == R_EDI
            || b == R_EAX || b == R_EBX || b == R_ECX || b == R_EDX
            || b == R_EBP || b == R_ESP || b == R_ESI || b == R_EDI)
            return (addrbits == 16);
        else
            return (addrbits == 32);
    } else
        return 0;
}

⌨️ 快捷键说明

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