我想知道汇编中的“语义NOP”是什么?
答案 0 :(得分:5)
不是实际nop但不影响程序行为的代码。
在C中,以下序列可以被认为是语义NOP:
{
// Since none of these have side affects, they are effectively no-ops
int x = 5;
int y = x * x;
int z = y / x;
}
答案 1 :(得分:1)
它们是无效的指令,如NOP,但需要更多字节。用于将代码与高速缓存行边界对齐。像lea edi,[edi + 0]这样的指令就是一个例子,它需要7个NOP来填充相同的字节数,但只需要1个周期而不是7个。
答案 2 :(得分:0)
语义NOP是机器语言指令的集合,它们完全没有效果或几乎没有效果(大多数指令更改条件代码),其唯一目的是模糊程序实际执行的操作。
答案 3 :(得分:0)
执行但没有做任何有意义的代码。这些也称为“不透明谓词”,最常用于obfuscators。
答案 4 :(得分:0)
真正的“语义nop”是除了花费一些时间和推进程序计数器之外没有任何效果的指令。例如,许多寄存器到寄存器移动不会影响标志的机器有许多将寄存器移动到自身的指令。例如,在8088上,以下任何一种都是语义NOP:
mov al,al mov bl,bl mov cl,cl ... mov ax,ax mob bx,bx mov cx,cx ... xchg ax,ax xchg bx,bx xchg cx,cx ...
注意除了“xchg ax,ax”之外的所有上述都是双字节指令。因此,英特尔宣布,当需要一个字节的NOP时,应使用“xchg ax,ax”。实际上,如果一个人组装“mov ax,ax”并将其拆解,它将被拆解为“NOP”。
请注意,在某些情况下,指令或指令序列可能具有潜在的副作用,但仍然比通常的“nop”更令人满意。例如,在6502上,如果需要7个周期的延迟并且堆栈指针有效但堆栈顶部值无关紧要,那么PHP后跟PLP将仅使用两个字节的代码就会终止七个周期。但是,如果栈顶值不是RAM的备用字节,则序列将失败。