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

在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: %dn", ovf);

这里我们递减一个有符号的8位值-128。 由于-128是最小的可能值,溢出是不可避免的。 如预期的那样,打印出来: Overflow flag: 1

但是当我们对一个无符号值做同样的处理时,这种行为并不如我所期望的那样:

int8_t ovf = 0;

__asm__
(
    "movb $255, %%bh;"
    "incb %%bh;"
    "seto %b0;"
    : "=g"(ovf)
    :
    : "%bh"
);

printf("Overflow flag: %dn", ovf);

这里我增加一个无符号8位值为255.由于255是最大的可能值,溢出是不可避免的。 但是,这会打印出来: Overflow flag: 0

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


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

char ovf = 0;

_asm {
    mov bh, 127
    inc bh
    seto ovf
}
cout << "ovf: " << int(ovf) << endl;

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

这也设置了OF:

char ovf = 0;

_asm {
    mov bh, 128
    dec bh
    seto ovf
}
cout << "ovf: " << int(ovf) << endl;

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


英特尔®64和IA-32架构软件开发人员手册

查看相应的手动指令集参考,AM。 每条指令都有详细记录。

以下是受影响标志的INC部分:

CF标志不受影响。 根据结果​​设置OF,SZ,ZF,AZ和PF标志。


尝试改变你的测试来传递数字而不是硬代码,然后有一个循环尝试所有256个数字来找到影响标志的数字。 或者让asm执行循环并在它碰到标志时退出,或者当它绕回到它开始的数字(从0x00,0x7f,0x80或0xFF以外的地方开始)。

编辑

.globl inc
inc:
    mov $33, %eax

top:
    inc %al
    jo done
    jmp top

done:
    ret

.globl dec
dec:
    mov $33, %eax

topx:
    dec %al
    jo donex
    jmp topx

donex:
    ret

Inc从0x7F到0x80时溢出。 dec从0x80到0x7F溢出,我怀疑问题在于你使用内联汇编程序的方式。

链接地址: http://www.djcxy.com/p/85925.html

上一篇: x86 Assembly: INC and DEC instruction and overflow flag

下一篇: Assembly