我填ecx与我想循环中,倍量decrease ecx和jump if not zero到back:。
现在的问题是,为什么不:
cmp ecx, 0
之前必需的jnz back。jnz跳转时如何自动知道要比较哪个寄存器?(ecx在这种情况下)。
int _tmain(int argc, _TCHAR* argv[])
{
int a = 0;
__asm
{
mov eax, 0
mov ecx, 4
back:
inc eax
sub ecx, 1
jnz back
mov a, eax
}
cout << a << endl; //outputs '4' properly
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在汇编中,有多个指令可用于执行“比较”。
通常(只有极少数例外),条件分支指令根本不比较任何寄存器。他们在EFLAGS寄存器中测试所谓的“状态标志”(零标志,进位标志等),并根据这些标志的状态确定是否执行跳转。
如您在此列表中看到的,某些指令甚至具有多个名称。例如,je(Ĵ UMP如果Ë QUAL)只是一个别名jz(Ĵ如果UMP Ž ERO标志被设置)。
至于cmp说明,它只是一个减法。它像执行减法一样设置标志,但是不保存值或修改其任何操作数。例如,如果您从12中减去10(通过cmp或sub),则清除零标志(因为结果不为零),并且清除进位标志(无需借用)。在这种情况下,根据零标志的状态,jnz((aka jne)将采用分支,而jz((aka je))将不会采取分支。
几乎所有的算术和按位指令都会影响这些标志以及其他标志。官方文档非常清楚每个指令会影响哪些标志。例如,dec cx还设置标志。如果in的值cx递减后为零,则将置零标志。因此,jnz不会跳,您会掉入循环。