x86汇编:INC和DEC指令和溢出标志

Cha*_*l72 13 c x86 assembly x86-64 inline-assembly

在x86汇编中,当有符号整数上的addsub操作溢出时,溢出标志置位,当无符号整数上的操作溢出时,置载标志置位.

然而,当谈到incdec说明,情况似乎有些不同.根据该网站,该inc指令根本不影响进位标志.

但我不能找到有关如何的任何信息incdec如果有的话,会影响溢出标志.

发生整数溢出时执行incdec设置溢出标志?对于有符号整数和无符号整数,这种行为是否相同?

============================= 编辑 ==================== =========

好的,基本上这里的共识是,就设置标志而言,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"
);

printf("Overflow flag: %d\n", ovf);
Run Code Online (Sandbox Code Playgroud)

在这里,我将无符号的8位值递增255.由于255是最大可能值,因此溢出是不可避免的.然而,这打印出来:Overflow flag: 0.

咦?为什么不在这种情况下设置溢出标志?

Fer*_*cio 16

当操作导致符号更改时,将设置溢出标志.你的代码非常接近.我能够使用以下(VC++)代码设置OF标志:

char ovf = 0;

_asm {
    mov bh, 127
    inc bh
    seto ovf
}
cout << "ovf: " << int(ovf) << endl;
Run Code Online (Sandbox Code Playgroud)

当BH递增时,MSB从0变为1,导致OF被置位.

这也设置OF:

char ovf = 0;

_asm {
    mov bh, 128
    dec bh
    seto ovf
}
cout << "ovf: " << int(ovf) << endl;
Run Code Online (Sandbox Code Playgroud)

请记住,处理器不区分有符号和无符号数字.使用2的补码算法时,可以使用一组指令来处理两者.如果要测试无符号溢出,则需要使用进位标志.由于INC/DEC不影响进位标志,因此在这种情况下需要使用ADD/SUB.