如何做符号的反义扩展从一个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?基本上与符号扩展相反。

注意:我在这里也包含了我的思维过程,因为我很可能做的事情并非如预期的那样,因此目前我找不到答案。

+4

符号扩展(如果它可以被称为)的相反是只是截断。这已经是你在做什么了。所以,如果这是不对的,请解释*应该发生什么 – harold

+0

@harold我对部分感到困惑。如果我有一个负16位数,那么MSB将是1,是正确的?如果我继续只使用较低的8位,那么我已经基本完全丢失了符号位,不是吗? – skiwi

+1

这段代码中没有分支,那么你遇到什么问题?更多上下文将有所帮助正如哈罗德所说,如果ax是一个从8位整数扩展而来的有符号整数,那么al就已经拥有你想要的。 – Andrew

这是我的观点的一个例子一点:如果相乘的结果是否定的,你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:  
+3

您可以使用JNL更高效地写入以跳过NEG,因此其中一个路径没有采用分支。 (当然[有无数的方法来获得一个整数的绝对值](https://godbolt.org/g/eV52mE)) –

我无法正确理解问题和评论中的后续行动。让我知道这是不是一个答案。

我还发现这个答案可能是@ Jose的一个副本,所以我正在考虑将其删除,特别是如果我发现我误解了这个问题。


随着imul bl我们要么有:

  1. AL * BL的结果融入AL(但结果是符号扩展至AX)。
  2. AL * BL的结果不符合AL

在后一种情况下必须选择做什么。
通常必须是按比例的结果返回到8位,这可以是作为解决比例2 简单:2 = AXALAL,或者可以是更复杂(包括根本不是一个规模或任何线性操作)。

在前一种情况下,我们需要计算结果的绝对值。
由于情况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

+0

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,根据需要设置标志。) –

+1

另外,我同意这个问题是非常有问题的。我没有看到OP如何确定BL的签名解释如果可能溢出,它总是“正面的”。 OP可能真的想要零扩展BL(无符号)和符号扩展AL(带符号)。为了清楚地解释这两种可能的结果而赞成这种结果,并且如果结果不合适,那么考虑AL的绝对值可能不是正确答案。 –

+0

@Peter,我认为这两种情况是相互排斥的:OP既可以排除情况1,也可以排除情况1。如果他们不能,他们可能错过了一些东西,问题没有答案。如果他们可以,那么采取* AL *的绝对值可以解决他们的问题。 –