-4

我如何签署合同 ff12.here 这是一个负数,但我需要在这里删除所有 FF 但如果我这样做,它就会变成一个正数。


可以在The Art of Assembly 的在线副本中找到“符号收缩”的一个定义,与 x86 等符号扩展相反cbw

符号收缩,将具有一些位数的值转换为具有较少位数的相同值,有点麻烦。标志扩展永远不会失败。给定一个 m 位有符号值,您始终可以使用符号扩展将其转换为 n 位数字(其中 n > m)。不幸的是,给定一个 n 位数,如果 m < n,您不能总是将其转换为 m 位数。例如,考虑值 -448。作为 16 位十六进制数,其表示形式为 $FE40。不幸的是,这个数字的大小太大而无法放入八位值,因此您无法将其签署为八位。这是转换时发生的溢出条件的示例。

4

1 回答 1

4

符号收缩如何从 16 位工作到 8 位?

它没有(最高的 8 位,如果值太大而无法放入 8 位,则包括符号位,被简单地丢弃)。

相反,您必须自己实现它。

如果“收缩”是“尽可能多地保留位”,那么它可能会变成这样:

    add ax,ax   ;carry flag = sign bit, al = lowest 7 bits shifted left
    rcr al,1    ;al = original sign bit with original lowest 7 bits

对于您的测试值 0xFF12(或十进制的 -238),在 . 之后变为“设置了进位标志的 0xFE24” add,然后在 . 之后变为 0x92(或十进制的 -110)rcr

更多示例(包括极端案例):

0xFF80 (or -128) -> "0xFF00 with carry flag set" = 0x80 (or -128)

0xFF00 (or -256) -> "0xFE00 with carry flag set" = 0x80 (or -128)

0x0000 -> "0x0000 with carry flag clear" = 0x00

0x007F (or +127) -> "0x00FE with carry flag clear" = 0x007F (or +127)

0x00FF (or +255) -> "0x01FE with carry flag clear" = 0x007F (or +127)

如果“收缩”是“饱和”(钳位值),那么它可能类似于:

    mov bx,ax    ;bx = original 16-bit value
    cbw          ;ax = 16-bit extension of original value in AL
    cmp ax,bx    ;Did the original value fit in 8 bits?
    je .done     ; yes, AL is correct (no saturation needed)

    add bx,bx    ;carry flag = original sign bit
    mov al,0x7F
    adc al,0     ;al = 0x80 (if value was negative) or 0x7F (if value was positive)
.done:

我不确定是否有更好的方法(它看起来很糟糕,我怀疑我的大脑今天不工作)。

于 2022-01-22T18:07:35.267 回答