我同意——slt 只需要在其操作数之间或多或少地回答,这可以在不发生溢出的情况下完成。
但我们可以进一步详细说明。
首先,让我们注意sub 需要发出溢出信号(通过抛出异常),因此除了仅 32 位减法运算之外,还使用了一些额外的逻辑来检测它。
因此,我们可以假设slt 除了仅仅 32 位减法之外还有一些额外的逻辑(它也与sub 不同,它捕获 0 或 1 结果,而不是直接捕获减法结果)。
sub 的这个额外逻辑可能是它对 33 位结果进行减法 - 如果 33 位与 32 位不同,则 32 位答案的幅度将是有损的,即溢出。
或者sub 的这个额外逻辑可能是它执行 32 位减法,并将输入的符号与结果的符号进行比较。如果输入的符号相同,则不会溢出,但如果输入的符号不同,并且结果的符号与被减数(第一个操作数)的符号不同,则发生溢出。
对于slt,可以像sub 那样检测溢出(在给出 33 位答案或比较 3 个符号方法的情况下计算 1 与 0 结果),但有一种非常简单的方法( a) 检测是否可能发生溢出,以及 (b) 在可能发生溢出时以简单的答案绕过子操作(或绕过子操作)。
所以,我会按照下表:
minuend subtrahend can slt
(source1) (source2) overflow? result
----------------------------------------------------------------
pos pos No sign of subtraction operation
pos neg Yes 0 (sign of minuend), ignore subtraction
neg pos Yes 1 (sign of minuend), ignore subtraction
neg neg No sign of subtraction operation
总而言之,如果输入的符号不同,则slt 结果是被减数的符号,否则 slt 结果是减法的符号(它不会溢出,因为输入的符号是一样)。
由于我们至少有 3 种实现策略可以在不存在溢出导致的错误风险的情况下获得答案,因此slt 没有必要引发异常。
(一个愚蠢的指令集架构确实可以为这条指令定义一个溢出异常,并在与sub相同的情况下抛出异常——这就像为slt的答案捕获减法结果的符号,而在这些情况下还会检测减法溢出和异常。)