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

📄 unwind.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 3 页
字号:

            case 0x2: // 5 Logical shift right by immediate
                if (shift == 0)
                    Op2 = 0;
                else
                    Op2 = Op2 >> shift;
                break;

            case 0x4: // 7 Arithmetic shift right by immediate
                if (shift == 0)
                    Op2 = 0;
                else
                    Op2 = (LONG)Op2 >> shift;
                break;

            case 0x6: // 9 Rotate right by immediate
                Op2 = _lrotl(Op2, shift);
                break;

            default:
                break;
            }
        }
    }

    // Determine the result (the new PC), based on the opcode.
    switch(instr.dataproc.opcode) {
    case OP_AND:
        Register[instr.dataproc.rd] = Op1 & Op2;
        break;

    case OP_EOR:
        Register[instr.dataproc.rd] = Op1 ^ Op2;
        break;

    case OP_SUB:
        Register[instr.dataproc.rd] = Op1 - Op2;
        break;

    case OP_RSB:
        Register[instr.dataproc.rd] = Op2 - Op1;
        break;

    case OP_ADD:
        Register[instr.dataproc.rd] = Op1 + Op2;
        break;

    case OP_ADC:
        Register[instr.dataproc.rd] = (Op1 + Op2) + Cflag;
        break;

    case OP_SBC:
        Register[instr.dataproc.rd] = (Op1 - Op2) - ~Cflag;
        break;

    case OP_RSC:
        Register[instr.dataproc.rd] = (Op2 - Op1) - ~Cflag;
        break;

    case OP_ORR:
        Register[instr.dataproc.rd] = Op1 | Op2;
        break;

    case OP_MOV:
        Register[instr.dataproc.rd] = Op2;
        break;

    case OP_BIC:
        Register[instr.dataproc.rd] = Op1 & ~Op2;
        break;

    case OP_MVN:
        Register[instr.dataproc.rd] = ~Op2;
        break;

    case OP_TST:
    case OP_TEQ:
    case OP_CMP:
    case OP_CMN:
    default:
        // These instructions do not have a destination register.
        // There is nothing to do.
        break;
    }
}



//------------------------------------------------------------------------------
//
//  Routine Description:
//      This function executes an ARM load multiple instruction.
//  
//  Arguments:
//      instr           The ARM 32-bit instruction
//  
//      Register        Pointer to the ARM integer registers.
//  
//  Return Value:
//      TRUE if successful, FALSE otherwise.
//
//------------------------------------------------------------------------------
BOOL
UnwindLoadMultiple(
    ARMI instr,
    PULONG Register
    )
{
    LONG i;
    ULONG RegList;
    PULONG Rn;

    // Load multiple with the PC bit set.  We are currently checking for all
    // four addressing modes, even though decrement before and increment
    // after are the only modes currently used in the epilog and prolog.
    //
    // Rn is the address at which to begin, and RegList is the bit map of which
    // registers to read.
    Rn = (PULONG)Register[instr.ldm.rn];
    RegList = instr.ldm.reglist;
    if (instr.ldm.p) {
        if (instr.ldm.u) {
            // Increment before
            for(i = 0; i <= 15; i++) {
                if (RegList & 0x1) {
                    Rn++;
                    if (!ReadMemory(Rn, &Register[i], 4))
                        return FALSE;
                }
                RegList = RegList >> 1;
            }
        } else {
            // Decrement before
            for(i = 15; i >= 0; i--) {
                if (RegList & 0x8000) {
                    Rn--;
                    if (!ReadMemory(Rn, &Register[i], 4))
                        return FALSE;
                }
                RegList = RegList << 1;
            }
        }
    } else {
        if (instr.ldm.u) {
            // Increment after
            for(i = 0; i <= 15; i++) {
                if (RegList & 0x1) {
                    if (!ReadMemory(Rn, &Register[i], 4))
                        return FALSE;
                    Rn++;
                }
                RegList = RegList >> 1;
            }
        } else {
            // Decrement after
            for(i = 15; i >= 0; i--) {
                if (RegList & 0x8000) {
                    if (!ReadMemory(Rn, &Register[i], 4))
                        return FALSE;
                    Rn--;
                }
                RegList = RegList << 1;
            }
        }
    }

    if (instr.ldm.w)
        Register[instr.ldm.rn] = (ULONG)Rn; // Update the base register.
    return TRUE;
}



//------------------------------------------------------------------------------
//
//  Routine Description:
//      This function executes an ARM load instruction with an immediat offset.
//  
//  Arguments:
//      instr           The ARM 32-bit instruction
//  
//      Register        Pointer to the ARM integer registers.
//  
//  Return Value:
//      TRUE if successful, FALSE otherwise.
//
//------------------------------------------------------------------------------
BOOL
UnwindLoadI(
    ARMI instr,
    PULONG Register
    )
{
    LONG offset;
    LONG size;
    PULONG Rn;

    Rn = (PULONG)Register[instr.ldr.rn];
    offset = instr.ldr.offset;
    if (instr.ldr.u == 0)
        offset = -offset;
    if (instr.ldr.b == 0)
        size = 4;
    else
        size = 1;

    if (instr.ldm.p) { // add offset before transfer
        if (!ReadMemory(Rn + offset, &Register[instr.ldr.rd], size))
            return FALSE;
        if (instr.ldr.w)
            Register[instr.ldr.rn] += offset;
    } else {
        if (!ReadMemory(Rn, &Register[instr.ldr.rd], size))
            return FALSE;
        if (instr.ldr.w)
            Register[instr.ldr.rn] += offset;
    }

    return TRUE;
}



//------------------------------------------------------------------------------
//
//  Routine Description:
//      Checks the condition codes of the instruction and the values of the
//      condition flags in the current program status register, and determines
//      whether or not the instruction will be executed.
//  
//  Arguments:
//      CPSR    -   The value of the Current Program Status Register.
//      instr   -   The instruction to analyze.
//  
//  Return Value:
//      TRUE if the instruction will be executed, FALSE otherwise.
//
//------------------------------------------------------------------------------
BOOL
CheckConditionCodes(
    ULONG CPSR,
    DWORD instr
    )
{
    BOOL Execute = FALSE;
    BOOL Nset = (CPSR & 0x80000000L) == 0x80000000L;
    BOOL Zset = (CPSR & 0x40000000L) == 0x40000000L;
    BOOL Cset = (CPSR & 0x20000000L) == 0x20000000L;
    BOOL Vset = (CPSR & 0x10000000L) == 0x10000000L;

    switch(instr & COND_MASK) {
    case COND_EQ:   // Z set
        if (Zset) Execute = TRUE;
        break;

    case COND_NE:   // Z clear
        if (!Zset) Execute = TRUE;
        break;

    case COND_CS:   // C set
        if (Cset) Execute = TRUE;
        break;

    case COND_CC:   // C clear
        if (!Cset) Execute = TRUE;
        break;

    case COND_MI:   // N set
        if (Nset) Execute = TRUE;
        break;

    case COND_PL:   // N clear
        if (!Nset) Execute = TRUE;
        break;

    case COND_VS:   // V set
        if (Vset) Execute = TRUE;
        break;

    case COND_VC:   // V clear
        if (!Vset) Execute = TRUE;
        break;

    case COND_HI:   // C set and Z clear
        if (Cset && !Zset) Execute = TRUE;
        break;

    case COND_LS:   // C clear or Z set
        if (!Cset || Zset) Execute = TRUE;
        break;

    case COND_GE:   // N == V
        if ((Nset && Vset) || (!Nset && !Vset)) Execute = TRUE;
        break;

    case COND_LT:   // N != V
        if ((Nset && !Vset) || (!Nset && Vset)) Execute = TRUE;
        break;

    case COND_GT:   // Z clear, and N == V
        if (!Zset &&
          ((Nset && Vset) || (!Nset && !Vset))) Execute = TRUE;
        break;

    case COND_LE:   // Z set, or N != V
        if (Zset ||
          ((Nset && !Vset) || (!Nset && Vset))) Execute = TRUE;
        break;

    case COND_AL:   // Always execute
        Execute = TRUE;
        break;

    default:
    case COND_NV:   // Never - undefined.
        Execute = FALSE;
        break;
    }
    return Execute;
}

⌨️ 快捷键说明

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