News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Simple multiply algorithm.

Started by hutch--, November 04, 2008, 01:09:12 PM

Previous topic - Next topic

KeepingRealBusy

Raymond,

I didn't know that. My book with Intel specs (Kip Irving) doesn't mention that at all. And I don't think that my AMD spec does either. I will have to check into this more.

Is this an Intel or AMD or both quirk? The hardware must be involved, it cannot be just an assembler allowance. I mean, not affecting the xDx reg. There must be some special preface byte generated.

This simple multiply is getting wierd!

Dave.

raymond

QuoteIs this an Intel or AMD or both quirk?

I don't know about AMD but I would assume with confidence that its processor would not be any different than Intel's. Directly from the Intel manual itself regarding the IMUL instruction:

QuoteWith the two- and three- operand forms, however, the result is truncated to the length of the destination before it is stored in the destination register.
When you assume something, you risk being wrong half the time
http://www.ray.masmcode.com

KeepingRealBusy

Raymond,

You are absolutely correct. Here it is straight from the AMD spec. I didn't realize this, but I have only really dealt with unsigned multiplies up to this point. My book from Kip Irving describing Intel operation (which came with MASM 615) gave the same formats (less the encodings), but did not even mention the two and three operand storage results.


Instruction Reference

24594   Rev. 3.12   September 2006 AMD64 Technology

IMUL Instruction Reference

Multiplies two signed operands. The number of operands determines the form of the instruction.

If a single operand is specified, the instruction multiplies the value in the specified general-purpose
register or memory location by the value in the AL, AX, EAX, or RAX register (depending on the
operand size) and stores the product in AX, DX:AX, EDX:EAX, or RDX:RAX, respectively.

If two operands are specified, the instruction multiplies the value in a general-purpose register (first
operand) by an immediate value or the value in a general-purpose register or memory location (second
operand) and stores the product in the first operand location.

If three operands are specified, the instruction multiplies the value in a general-purpose register or
memory location (second operand), by an immediate value (third operand) and stores the product in a
register (first operand).

The IMUL instruction sign-extends an immediate operand to the length of the other register/memory
operand.

The CF and OF flags are set if, due to integer overflow, the double-width multiplication result cannot
be represented in the half-width destination register. Otherwise the CF and OF flags are cleared.

IMUL Signed Multiply

Mnemonic             Opcode    Description

IMUL reg/mem8         F6 /5       Multiply the contents of AL by the contents of an 8-bit
                                                               memory or register operand and put the signed result in AX.

IMUL reg/mem16         F7 /5       Multiply the contents of AX by the contents of a 16-bit
                                                               memory or register operand and put the signed result in DX:AX.

IMUL reg/mem32         F7 /5       Multiply the contents of EAX by the contents of a 32-bit
                                                               memory or register operand and put the signed result in EDX:EAX.

IMUL reg/mem64         F7 /5       Multiply the contents of RAX by the contents of a 64-bit
                                                               memory or register operand and put the signed result in RDX:RAX.

IMUL reg16, reg/mem16     0F AF /r     Multiply the contents of a 16-bit destination register by
                                                               the contents of a 16-bit register or memory operand and
                                                               put the signed result in the 16-bit destination register.

IMUL reg32, reg/mem32     0F AF /r    Multiply the contents of a 32-bit destination register by
                                                               the contents of a 32-bit register or memory operand and
                                                               put the signed result in the 32-bit destination register.

IMUL reg64, reg/mem64     0F AF /r    Multiply the contents of a 64-bit destination register by
                                                               the contents of a 64-bit register or memory operand and
                                                               put the signed result in the 64-bit destination register.

IMUL reg16, reg/mem16, imm8 6B /r ib      Multiply the contents of a 16-bit register or memory
                                                               operand by a sign-extended immediate byte and put the
                                                               signed result in the 16-bit destination register.

IMUL reg32, reg/mem32, imm8 6B /r ib      Multiply the contents of a 32-bit register or memory
                                                               operand by a sign-extended immediate byte and put the
                                                               signed result in the 32-bit destination register.

IMUL reg64, reg/mem64, imm8 6B /r ib      Multiply the contents of a 64-bit register or memory
                                                               operand by a sign-extended immediate byte and put the
                                                               signed result in the 64-bit destination register.

IMUL reg16, reg/mem16, imm16   69 /r iw      Multiply the contents of a 16-bit register or memory
                                                              operand by a sign-extended immediate word and put the
                                                              signed result in the 16-bit destination register.

IMUL reg32, reg/mem32, imm32   69 /r id      Multiply the contents of a 32-bit register or memory
                                                              operand by a sign-extended immediate double and put
                                                              the signed result in the 32-bit destination register.

IMUL reg64, reg/mem64, imm32   69 /r id      Multiply the contents of a 64-bit register or memory
                                                              operand by a sign-extended immediate double and put
                                                              the signed result in the 64-bit destination register.

IMUL reg32, reg/mem32, imm8     6B /r ib      Multiply the contents of a 32-bit register or memory
                                                               operand by a sign-extended immediate byte and put the
                                                               signed result in the 32-bit destination register.

IMUL reg64, reg/mem64, imm8     6B /r ib      Multiply the contents of a 64-bit register or memory
                                                               operand by a sign-extended immediate byte and put the
                                                               signed result in the 64-bit destination register.

IMUL reg16, reg/mem16, imm16    69 /r iw      Multiply the contents of a 16-bit register or memory
                                                                operand by a sign-extended immediate word and put the
                                                                signed result in the 16-bit destination register.

IMUL reg32, reg/mem32, imm32    69 /r id       Multiply the contents of a 32-bit register or memory
                                                                operand by a sign-extended immediate double and put
                                                                the signed result in the 32-bit destination register.

IMUL reg64, reg/mem64, imm32    69 /r id       Multiply the contents of a 64-bit register or memory
                                                                operand by a sign-extended immediate double and put
                                                                the signed result in the 64-bit destination register.


Dave.

jj2007

So all that means we need a better way of handling this. Proposal:

smul MACRO accu:REQ, mult:REQ
  ifdifi <accu>, <eax>
mov eax, accu
  endif
  if opattr (mult) eq 36   ; immediate
mov edx, mult
imul edx
  else
imul mult
  endif
  EXITM <eax>
ENDM

.data
mem4 dd 10000h

.code
start:
print chr$(13, 10, "edx=")
mov edi, smul(12345678h, 10000h) ; immediate * immediate
print hex$(edx)
print ", eax="
print hex$(edi)

print chr$(13, 10, "edx=")
mov edi, smul(12345678h, mem4) ; immediate * mem32
print hex$(edx)
print ", eax="
print hex$(edi)

print chr$(13, 10, "edx=")
mov edx, 10000h
mov edi, smul(12345678h, edx) ; immediate * reg32
print hex$(edx)
print ", eax="
print hex$(edi)

print chr$(13, 10, "edx=")
mov edx, 10000h
mov eax, 12345678h
mov edi, smul(eax, edx) ; reg32 * reg32
print hex$(edx)
print ", eax="
print hex$(edi)

print chr$(13, 10, "edx=")
mov edx, 10000h
mov mem4, 12345678h
mov edi, smul(mem4, edx) ; mem32 * reg32
print hex$(edx)
print ", eax="
print hex$(edi)

Output:

edx=00001234, eax=56780000
edx=00001234, eax=56780000
edx=00001234, eax=56780000
edx=00001234, eax=56780000
edx=00001234, eax=56780000

vanjast

I'm using a redundant EDX a lot in this calculation section .... I haven't finalised it but it it's close to the same idea of the topic

;--- EXTENDED GREGORIAN DATE SECTION ---
Mov Eax, myMonth ;Load Month (M)
Mov Ebx, myYear         ;load Year (Y)
Cmp Eax, c003 ;Is Month - Jan or Feb
Jge @F ;Nope - skip next instruction
Dec Ebx ;Decrement year value

@@: ;(Y + (M-9)/7)
Mov Eax, Ebx ;Move year value
Mov Ebx, c100 ;Load denominator (= 100)
Cdq ;Sign extend EDX:EAX for DIV
Div Ebx ;((Y + (M-9)/7) / 100)
Add Eax, c001 ;((Y + (M-9)/7) / 100) + 1
Mov Ebx, c003 ;Load 3
Mul Ebx ;3*(((Y + (M-9)/7) / 100) + 1)
Mov Ebx, c004 ;Load denominator (= 4)
Cdq ;Sign extend EDX:EAX for DIV
Div Ebx ;(3*(((Y + (M-9)/7) / 100) + 1)) / 4
Mov myJulianDay, Eax ;Saved


Now looking at it, i can improve via swopping EAX, EBX  parameter storage... just as well I read this topic... :lol