在控制语句的指令生成过程中, 语句无法知道外界指令结构, 不能贸然将跳出语句定向到外部指令, 因此使用了 NOP 指令缓冲了这些跳转. 然而, 在全部指令生成结束后, 跳转指令就可以根据上下文选择正确的目标了, 那么 NOP 指令只是影响性能的冗余指令了. 本着兔死狗烹的原则, 现在去掉这些指令.
static void cleanNop(struct List* instructions);
具体的做法是, 为每个 NOP 指令记录它之后的第一条非 NOP 指令, 然后扫描指令序列, 重定向它们的目标, 然后删去全部 NOP 指令. 现在先给指令数据结构增加一个索引域
/* 增加 index 域 */
#define memberAbstractInstruction \
int segOffset; \
int index; \
InstructionCode code; /*******/
struct AbstractInstruction {
memberAbstractInstruction
};
对于非 NOP 指令, 它的索引域等于它自己的位置索引, 而 NOP 指令的索引域等于该指令之后第一条非 NOP 指令的索引.
对整个指令序列进行一次逆向遍历, 计算它们的索引值
int index = instructions->count(instructions) - 1;
int lastOpInd;
struct AbstractInstruction* ins;
for (; index >=0; --index) {
ins = (struct AbstractInstruction*)
(instructions->elementAt(instructions, index));
if (NOP != ins->code) {
lastOpInd = index;
}
ins->index = lastOpInd;
}
扫描并重定向全部的跳转指令
struct Iterator* iterator;
for_each (iterator, instructions) {
ins = (struct AbstractInstruction*)(iterator->current(iterator));
if (isJump(ins->code)) {
struct JumpInstruction* jmp = (struct JumpInstruction*)ins;
jmp->targetIns = instructions->elementAt(instructions,
jmp->targetIns->index);
}
}
删除 NOP 指令. 任务完成.
for_each (iterator, instructions) {
if (NOP == ((struct AbstractInstruction*)
(iterator->current(iterator)))->code) {
revert(iterator->current(iterator));
iterator->remove(iterator);
}
}
现在的修改版本中, 输出指令的代码被移入新文件, 减少了 jerry-compiler.c 的混乱程度.
void fakeDefaultAnalyserConsumeNT(void* self, struct AbstractSyntaxNode* node)
{
if (NULL == node) {
return;
}
node = (struct AbstractSyntaxNode*)newBasicBlockNode(node);
initStack(&loopStack);
initialSymTabManager();
struct List* insList = node->createInstruction(node);
node->delNode(node);
finalizeSymTabManager();
loopStack.finalize(&loopStack);
if (isFailed()) {
while (0 != insList->count(insList)) {
revert(insList->popElementAt(insList, 0));
}
cresult = ERROR_IN_SRC;
return;
}
struct NoParamInstruction* endProg = (struct NoParamInstruction*)
allocate(sizeof(struct NoParamInstruction));
endProg->code = END_PROGRAM;
insList->addTo(insList, endProg, insList->count(insList));
/* 原先在这里的代码, 以及 writeInstruction 函数被移入了
instruction-process.cpp / instruction-process.h */
ErrMsg err = processIns(insList, treeout);
if (NULL != err) {
fputs(err, stderr);
cresult = IO_ERROR;
}
insList->finalize(insList);
}
编译器/解释器构造到此结束, 也许我还会改改 Jerry, 不过不保证, 哈~
分享到:
相关推荐
NOP指令为单周期指令,可由晶振频率算出延时时间,对于12M晶振,延时1uS。对于延时比较长的,要求在大于10us,采用C51中的循环语句来实现。 方法2: 插入方式: __asm //是两个下划线 { nop; }
NOP指令为单周期指令,可由晶振频率算出延时时间,对于12M晶振,延时1uS。 第二种情况是对于延时比较长的,要求在大于10us,采用C51中的循环语句来实现。在选择C51中的循环语句时,要注意以下几个问题: 1. 定义的...
而NOP指令本身就是一个指令周期,因此执行一个NOP指令的时间就是1个CPU指令周期的时间。根据前面的分析,这也就是1.67MHz的倒数,即大约0.6微秒(µs)。 因此,在CPU频率为20MHz的情况下,执行一个NOP指令大约需要...
标题中的“nop.rar_nop_nop键盘”暗示了我们讨论的主题是关于计算机编程中的NOP指令以及与键盘交互的实现。NOP,全称是"No Operation",在计算机指令集中,它通常表示一个空操作或者无操作指令。NOP指令在程序设计中...
4. **插入NOP指令**:在Ollydbg中,选择要替换的跳转指令,右键点击并选择“Patch byte”或“Edit byte”,将跳转指令替换为NOP(`0x90`)。如果需要插入多个NOP,重复此过程。 5. **调整跳转目标**:现在,你需要...
标准的C语言中没有空语句。但在单片机的C语言编程中,经常需要用几个空指令产生短延时的效果。 这在汇编语言中很容易实现,写几个nop就行了。
NOP指令为单周期指令,可以由晶振频率算出延时时间,对于12M晶振,延时1uS。 在Keil C51中,可以直接调用库函数#include<intrins.h> void _nop_(void);_nop_();来产生一条NOP指令。nop函数的使用可以满足对于延时很...
处理器使用的是ARMv6-M Thumb指令集,包括大量的32位的使用Thumb-2技术的指令。表7-22列出了Cortex-M0指令和它们的周期数。周期计数以零等待状态的系统为基准
- **注释**:nop指令不执行任何操作,主要用于调试目的或作为流水线中的填充指令。 - **用途**:通常用来调整指令执行的时间,例如为了实现特定的同步效果。 2. **addi (Add Immediate)** - **执行周期**:1 - ...
`,然后使用`_nop_()`函数来产生一条NOP指令,这个函数相当于汇编NOP指令,延时几微秒。 对于延时很短的,要求在us级的,可以采用“_nop_”函数来实现。NOP指令为单周期指令,可以由晶振频率算出延时时间,对于12M...
标题中的“nop19中文包”多次重复,可能是指一个针对NOP19编程语言或框架的中文资源包。NOP19可能是一个特定的版本或者一个专门为学习或开发目的设计的工具。由于信息有限,我们首先假设这是一个编程环境或库的中文...
2. **延时程序**:给定程序通过MOV、NOP和DJNZ指令实现延时,其中NOP指令用于插入一个机器周期的空闲时间。若要延时50us,需计算R3的初始值以确保执行循环次数正确。 3. **数值相加**:该程序将两个位于内存40H和...
Nop平台低代码前端设计源码:该项目基于Javascript开发,包含1549个文件,主要使用TypeScript、...nop-chaos是Nop平台的前端部分,采用了Vue3.0、ant-design-vue、百度AMIS、logicflow、xspreadsheet等技术实现。
由于C语言的时序性相对较弱,实现精确延时较为困难,通常需要借助汇编语言的空操作(NOP)指令来完成。在AVR C程序中,我们可以通过定义一系列宏来实现这一目标,简化代码书写并确保延时精度。 首先,我们需要为1到...
"1500 SCL 指令用法" 该资源介绍了 Siemens S7-1200 和 S7-1500 PLC 系统中 SCL 指令的使用方法。SCL 指令是一种基于文本的编程语言,用于编写 PLC 程序。 位逻辑运算 SCL 指令提供了多种位逻辑运算,包括与、或、...
NOP指令是一种空操作指令,用于占用 CPU 的时钟周期,但不执行任何操作。 ADD和ADDC指令 ADD和ADDC指令是51单片机中的一种加法指令,用于将两个寄存器或存储器的值相加。ADDC指令用于带 CY 的加法。 SUBB指令 ...
空操作指令NOP是程序控制类指令中的一种,用于执行空操作。该指令不影响用户程序的执行,操作数N是标号,是一个0~255的常数。 NOP指令的格式为:NOP N 例如:NOP 30 5.1.2 结束及暂停 结束及暂停指令有两条:END...
程序员有时会用nop填充代码来替换原有指令,可能是为了调试、优化或者在某些条件下禁用特定代码块。 在"feature-fixups-test.c"这个C语言源文件中,很可能包含了一个或多个函数或代码段,这些代码可能在特定情况下...
NOP功能: NOP指令用于程序开头指令。例如 NOPTIME功能: TIME指令用于暂停时间。例如 T=12.50暂停 12.5 秒后执行下一指令。 CWAIT功能: CWAIT指令用于等待 NWAIT 指令,那一行指令执行完毕才继续执行下一行指令。...
在FPGA开发中,理解并熟练使用这样的NPU指令集对于优化神经网络的硬件实现至关重要,因为它直接影响到计算速度和功耗效率。通过精心设计指令序列,可以构建出能够高效执行各种神经网络模型的定制化硬件加速器。