如何做符号的反义扩展从一个16位寄存器到一个8位寄存器?
我正在使用x86汇编,我已经开始使用MUL
指令了。如何做符号的反义扩展从一个16位寄存器到一个8位寄存器?
以前是这个我的代码片断:
mov al, <some_number>
mul bl
add al, [edi]
mov [edi], al
凡<some_number>
是本大会片段之外定义一个常数,它可以是正数或负。 bl
寄存器在代码的早期设置,它总是正的(因为它只是在每次合适时溢出/下溢)。我也可以优化最后两条语句到add [edi], al
,但我不是100%确定的,所以我现在不会那样做。
所以我的程序打了未定义的行为,在这种情况下是一个无限循环,经过长时间检查什么可能是错误的,我想我必须使用IMUL
,因为<some_number>
可能是负数。
但现在它仍然无法正常工作。然后,我再次查看手册,并且看到mul bl
实际上将结果存储在ax
中。所以我有一个ax
签名的结果,而我想在al
无符号(具有上溢/下溢)结果。
所以我的问题是:如何把在ax
签名的结果为无符号之一al
?基本上与符号扩展相反。
注意:我在这里也包含了我的思维过程,因为我很可能做的事情并非如预期的那样,因此目前我找不到答案。
这是我的观点的一个例子一点:如果相乘的结果是否定的,你NEG
它,如果它是积极的,你不NEG
它(我在我的编译器的一个运行此代码):
mov bl, -5 ;◄■■ NEGATIVE NUMBER.
mov al, 10
imul bl ;◄■■ AX = -50 (0xFFCE).
cmp ax, 0
jl negative ;◄■■ IF AX < 0 JUMP TO NEGATIVE.
jmp continue ;◄■■ IF AX >= 0 SKIP NEGATIVE.
negative:
neg ax ;◄■■ AX => POSITIVE (0xFFCE => 0x32).
continue:
您可以使用JNL更高效地写入以跳过NEG,因此其中一个路径没有采用分支。 (当然[有无数的方法来获得一个整数的绝对值](https://godbolt.org/g/eV52mE)) –
我无法正确理解问题和评论中的后续行动。让我知道这是不是一个答案。
我还发现这个答案可能是@ Jose的一个副本,所以我正在考虑将其删除,特别是如果我发现我误解了这个问题。
随着imul bl
我们要么有:
-
AL * BL的结果融入
AL
(但结果是符号扩展至AX
)。 -
AL * BL的结果不符合
AL
。
在后一种情况下你必须选择做什么。
通常必须是按比例的结果返回到8位,这可以是作为解决比例2 简单:2 = AX:AL为AL,或者可以是更复杂(包括根本不是一个规模或任何线性操作)。
在前一种情况下,我们需要计算结果的绝对值。
由于情况1假定结果符合AL
,所以寄存器AH
或者全为零或者全为1,匹配AL
的符号位。
imul bl ;Original code
xor al, ah ;NOT AL iif the result is negative
sub al, ah ;AL = AL - (-1) = AL + 1 iif the result is negative
这利用了公知的身份,两两的补,NEG(X)=未(X)+ 1。
IMUL设置OF和CF如果'full_result!= sign_extend(low_half_result)',那么您可以通过按照IMUL设置的CF或OF分支来检测情况1与情况2。看到[这个相关的问题](http://stackoverflow.com/a/38254324/224132)关于IMUL的标志设置的更多讨论,相反的问题:使用2操作数IMUL r64,r64,仍然检测* unsigned * wraparound的64位低半结果。 (tl; dr:只需使用MUL r64,根据需要设置标志。) –
另外,我同意这个问题是非常有问题的。我没有看到OP如何确定BL的签名解释如果可能溢出,它总是“正面的”。 OP可能真的想要零扩展BL(无符号)和符号扩展AL(带符号)。为了清楚地解释这两种可能的结果而赞成这种结果,并且如果结果不合适,那么考虑AL的绝对值可能不是正确答案。 –
@Peter,我认为这两种情况是相互排斥的:OP既可以排除情况1,也可以排除情况1。如果他们不能,他们可能错过了一些东西,问题没有答案。如果他们可以,那么采取* AL *的绝对值可以解决他们的问题。 –
符号扩展(如果它可以被称为)的相反是只是截断。这已经是你在做什么了。所以,如果这是不对的,请解释*应该发生什么 – harold
@harold我对部分感到困惑。如果我有一个负16位数,那么MSB将是1,是正确的?如果我继续只使用较低的8位,那么我已经基本完全丢失了符号位,不是吗? – skiwi
这段代码中没有分支,那么你遇到什么问题?更多上下文将有所帮助正如哈罗德所说,如果ax是一个从8位整数扩展而来的有符号整数,那么al就已经拥有你想要的。 – Andrew