来自Ira Baxter回答,为什么INC和DEC指令不会影响进位标志(CF)?
大多数情况下,我远离
INC而DEC现在,因为他们做的部分条件代码更新,这样就可以在管道中引起滑稽的摊位,和ADD/SUB没有.因此,无关紧要(大多数地方),我使用ADD/SUB避免失速.我使用INC/DEC仅在保持代码较小的情况下,例如,适合高速缓存行,其中一个或两个指令的大小产生足够的差异.这可能是毫无意义的纳米[字面意思!] - 优化,但我在编码习惯上相当老派.
我想问一下为什么它会导致管道中的停顿,而添加不会?毕竟,无论是ADD和INC更新标志寄存器.唯一的区别是INC不更新CF.但为什么重要呢?
在x86汇编中,当有符号整数上的add或sub操作溢出时,溢出标志置位,当无符号整数上的操作溢出时,置载标志置位.
然而,当谈到inc和dec说明,情况似乎有些不同.根据该网站,该inc指令根本不影响进位标志.
但我不能找到有关如何的任何信息inc和dec如果有的话,会影响溢出标志.
发生整数溢出时执行inc或dec设置溢出标志?对于有符号整数和无符号整数,这种行为是否相同?
============================= 编辑 ==================== =========
好的,基本上这里的共识是,就设置标志而言,INC和DEC应该与ADD和SUB的行为相同,但进位标志除外.这也是英特尔手册中的内容.
问题是,当涉及到无符号整数时,我实际上无法在实践中重现这种行为.
请考虑以下汇编代码(使用GCC内联汇编以便更轻松地打印结果.)
int8_t ovf = 0;
__asm__
(
"movb $-128, %%bh;"
"decb %%bh;"
"seto %b0;"
: "=g"(ovf)
:
: "%bh"
);
printf("Overflow flag: %d\n", ovf);
Run Code Online (Sandbox Code Playgroud)
这里我们递减一个带符号的8位值-128.由于-128是可能的最小值,溢出是不可避免的.正如所料,这打印出:Overflow flag: 1
但是当我们使用无符号值执行相同操作时,行为并不像我预期的那样:
int8_t ovf = 0;
__asm__
(
"movb $255, %%bh;"
"incb %%bh;"
"seto %b0;"
: "=g"(ovf)
:
: "%bh"
); …Run Code Online (Sandbox Code Playgroud) 我刚刚查看了彼得·科德斯(Peter Cordes)的回答,他说,
如果读取标志,则部分标志停顿会发生,如果它们确实发生的话。P4永远不会有部分标志停顿,因为它们永远不需要合并。相反,它具有错误的依赖关系。几个答案/评论混淆了术语。它们描述了一个错误的依赖关系,但随后将其称为部分标志停顿。这是由于仅写入一些标志而导致的速度下降,但是术语“部分标志停顿”是指必须合并部分标志写入时在SnB之前的Intel硬件上发生的情况。英特尔SnB系列CPU插入一个额外的uop来合并标志而不会停顿。Nehalem和更早的失速约7个周期。我不确定AMD CPU会受到多大的损失。
我感觉我还不明白什么是“部分国旗摊位”。我怎么知道一个人发生了?除了读取标志的某些时间之外,什么触发事件?合并标志是什么意思?在什么情况下会“写一些标志”,但不会发生部分标志合并?我需要了解哪些有关旗位的知识才能理解它们?
设置均值flag value = 1和未设置均值flag value = 0
现在我了解有几种方法可以在MASM中设置和取消设置标志,如下所示:
test al,0 ; set Zero flag
and al,0 ; set Zero flag
or al,1 ; clear Zero flag
Run Code Online (Sandbox Code Playgroud)
同样适用于Sign flag:
or al,80h ; set Sign flag
and al,7Fh ; clear Sign flag
Run Code Online (Sandbox Code Playgroud)
要设置Carry flag,我们使用STC指令; 要清除Carry标志,我们使用CLC:
stc ; set Carry flag
clc ; clear Carry flag
Run Code Online (Sandbox Code Playgroud)
要设置Overflow flag,我们添加两个产生负和的正值.要清除Overflow flag,我们OR操作数为0:
mov al,7Fh ; AL = +127
inc al ; AL = 80h (-128), …Run Code Online (Sandbox Code Playgroud)