我将ecx
填入我想要循环的次数,dec
将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;
}
答案 0 :(得分:4)
在汇编中,有多个指令可用于执行“比较”。
通常(只有极少数例外),条件分支指令根本不比较任何寄存器。他们在EFLAGS
寄存器中测试所谓的“状态标志”(零标志,进位标志等),并根据这些标志的状态确定是否执行跳转。 p>
正如您所见in this list,某些说明甚至有多个名称。例如,je
( J ump,如果 E qual)只是jz
的别名( J ump if设置 Z ero标志。)
对于cmp
指令,它只是一个减法。它将标志设置为好像已执行减法,但不保存值或修改其任何操作数。例如,如果从12减去10(通过cmp
或sub
),则清零零标志(因为结果不为零)并且进位标志被清除(没有必要借)。在这种情况下,根据零标志的状态,jnz
(aka jne
)将采用分支,而jz
(aka je
)则不会。
几乎所有算术和按位指令都会影响这些标志以及其他一些标志。官方文档清楚地说明了哪些标志受每条指令的影响。例如,dec cx
也设置标志。如果cx
中的值在递减后为零,则将设置零标志。因此,jnz
不会跳跃,你将失去循环。