符号的反义如何从16位寄存器扩展到8位寄存器?

时间:2016-11-29 21:24:46

标签: assembly x86

我正在使用x86 Assembly,我已经满足了使用MUL指令的需要。

我的代码片段曾经是这样的:

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中的无符号结果?基本上与符号扩展相反。

注意:我在这里也包含了我的思考过程,因为我很可能不是按照预期做事,因此到目前为止我找不到答案。

2 个答案:

答案 0 :(得分:3)

  

我无法正确理解问题以及评论中的后续行动。如果这根本不是答案,请告诉我。

     

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

使用imul bl,我们要么:

  1. AL * BL 的结果符合AL(但结果是符号扩展为AX)。
  2. AL * BL 的结果不适合AL
  3. 在后一种情况下必须选择做什么 通常,您必须将结果缩放回8位,这可以像解决比例2 16 一样简单:2 8 = 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)= not(x)+ 1

答案 1 :(得分:1)

这是我在一个例子中的观点:如果乘法的结果为负,你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: