Choco the Jailed
Choco the Jailed

Reputation: 11

imul dx with negative numbers produces large positive numbers in EAX?

; test.asm  

segment .bss
extern  _a, _b, _x, _y

segment .text
global  _compute
_compute:

    mov ax,[_a]
    mov dx,[_x]
    imul    dx
    mov dword[_y],eax

    mov ebx,[_b]
    add dword[_y],ebx

    ret

There is no problem when calculating positive numbers, but when calculating negative numbers, the results look strange, such as "65544" and "65542." How shall I do it?

Upvotes: 0

Views: 204

Answers (1)

Nate Eldredge
Nate Eldredge

Reputation: 58518

The 16-bit form of one-operand imul leaves the product in dx:ax, not in eax, even in 32-bit mode. It matches the behavior from 16-bit 8086 which had no 32-bit registers.

So you could do

    mov ax, [_a]
    mov dx, [_x]
    imul dx
    mov [_y], ax
    mov [_y+2], dx

But in 32-bit mode it may be nicer to sign-extend your 16 bit operands to 32 bits, and then do a non-widening 32-bit multiply (two-operand imul). 16-bit instructions are awkward because they need operand-size prefixes, and because they leave the high 16 bits of the 32 bit registers intact, potentially leading to performance problems because of the dependency. So another choice is something like

    movsx eax, word [_a]
    movsx edx, word [_x]
    imul eax, edx
    mov [_y], eax

Upvotes: 4

Related Questions