在32位架构上乘以两个十位32位数

时间:2016-05-02 16:38:39

标签: assembly x86 masm irvine32 largenumber

我必须在屏幕上阅读,存储和打印两个32位数字,然后将它们相乘并打印结果。

我已经阅读了这两个数字的数字,并且能够打印它们,但是如果它们足够大,它们会溢出,而不是提到这个事实,我必须将它们相乘,我不能使用64位寄存器。我找到了“多精度算术”的东西,但是无法实现它。我知道我必须使用eax:edx寄存器,而且我也读过有关进位的内容,仍然无法掌握它的本质。 (MASM,32位系统)

到目前为止我的代码:

INCLUDE Irvine32.inc
.data

NUM1        BYTE ?
NUM2        BYTE ?
NUM3        BYTE ?
NUM4        BYTE ?
NUM5        BYTE ?
NUM6        BYTE ?
NUM7        BYTE ?
NUM8        BYTE ?
NUM9        BYTE ?
NUM10   BYTE ?

NUMA        BYTE ?
NUMB        BYTE ?
NUMC        BYTE ?
NUMD        BYTE ?
NUME        BYTE ?
NUMF        BYTE ?
NUMG        BYTE ?
NUMH        BYTE ?
NUMI        BYTE ?
NUMJ        BYTE ?

SZAM1   DWORD   0
SZAM2   DWORD   0
SZAMOL  DWORD   0



.code
main proc

elso:
    call ReadChar
     mov  NUM1,al
    call WriteChar
    cmp AL,13
    JE masodik
    call ReadChar
     mov  NUM2,al
    call WriteChar
    cmp AL,13
    JE masodik
    call ReadChar
     mov  NUM3,al
    call WriteChar
    cmp AL,13
    JE masodik
    call ReadChar
     mov  NUM4,al
    call WriteChar
    cmp AL,13
    JE masodik
    call ReadChar
     mov  NUM5,al
    call WriteChar
    cmp AL,13
    JE masodik
    call ReadChar
     mov  NUM6,al
    call WriteChar
    cmp AL,13
    JE masodik
    call ReadChar
     mov  NUM7,al
    call WriteChar
    cmp AL,13
    JE masodik
    call ReadChar
     mov  NUM8,al
    call WriteChar
    cmp AL,13
    JE masodik
    call ReadChar
     mov  NUM9,al
    call WriteChar
    cmp AL,13
    JE masodik
    call ReadChar
     mov  NUM10,al
    call WriteChar
    cmp AL,13
    JE masodik



masodik:
    Call Crlf
    call ReadChar
     mov  NUMA,al
    call WriteChar
    cmp AL,13
    JE konvertal
    call ReadChar
     mov  NUMB,al
    call WriteChar
    cmp AL,13
    JE konvertal
    call ReadChar
     mov  NUMC,al
    call WriteChar
    cmp AL,13
    JE konvertal
    call ReadChar
     mov  NUMD,al
    call WriteChar
    cmp AL,13
    JE konvertal
    call ReadChar
     mov  NUME,al
    call WriteChar
    cmp AL,13
    JE konvertal
    call ReadChar
     mov  NUMF,al
    call WriteChar
    cmp AL,13
    JE konvertal
    call ReadChar
     mov  NUMG,al
    call WriteChar
    cmp AL,13
    JE konvertal
    call ReadChar
     mov  NUMH,al
    call WriteChar
    cmp AL,13
    JE konvertal
    call ReadChar
     mov  NUMI,al
    call WriteChar
    cmp AL,13
    JE konvertal
    call ReadChar
     mov  NUMJ,al
    call WriteChar
    cmp AL,13
    JE konvertal

konvertal:
    Call Crlf

    sub NUM1, '0'
    sub NUM2, '0'
    sub NUM3, '0'
    sub NUM4, '0'
    sub NUM5, '0'
    sub NUM6, '0'
    sub NUM7, '0'
    sub NUM8, '0'
    sub NUM9, '0'
    sub NUM10, '0'

    sub NUMA, '0'
    sub NUMB, '0'
    sub NUMC, '0'
    sub NUMD, '0'
    sub NUME, '0'
    sub NUMF, '0'
    sub NUMG, '0'
    sub NUMH, '0'
    sub NUMI, '0'
    sub NUMJ, '0'

szamkiiras1:
    mov al,NUM10
    movzx eax,al
    imul eax,1
    add SZAM1,eax

    mov al,NUM9
    movzx eax,al
    imul eax,10
    add SZAM1,eax

    mov al,NUM8
    movzx eax,al
    imul eax,100
    add SZAM1,eax

    mov al,NUM7
    movzx eax,al
    imul eax,1000
    add SZAM1,eax

    mov al,NUM6
    movzx eax,al
    imul eax,10000
    add SZAM1,eax

    mov al,NUM5
    movzx eax,al
    imul eax,100000
    add SZAM1,eax

    mov al,NUM4
    movzx eax,al
    imul eax,1000000
    add SZAM1,eax

    mov al,NUM3
    movzx eax,al
    imul eax,10000000
    add SZAM1,eax

    mov al,NUM2
    movzx eax,al
    imul eax,100000000
    add SZAM1,eax

    mov al,NUM1
    movzx eax,al
    imul eax,1000000000
    add SZAM1,eax

    mov eax,SZAM1
    call WriteInt

szamkiiras2:
    Call Crlf
    mov al,NUMJ
    movzx eax,al
    imul eax,1
    add SZAM2,eax

    mov al,NUMI
    movzx eax,al
    imul eax,10
    add SZAM2,eax

    mov al,NUMH
    movzx eax,al
    imul eax,100
    add SZAM2,eax

    mov al,NUMG
    movzx eax,al
    imul eax,1000
    add SZAM2,eax

    mov al,NUMF
    movzx eax,al
    imul eax,10000
    add SZAM2,eax

    mov al,NUME
    movzx eax,al
    imul eax,100000
    add SZAM2,eax

    mov al,NUMD
    movzx eax,al
    imul eax,1000000
    add SZAM2,eax

    mov al,NUMC
    movzx eax,al
    imul eax,10000000
    add SZAM2,eax

    mov al,NUMB
    movzx eax,al
    imul eax,100000000
    add SZAM2,eax

    mov al,NUMA
    movzx eax,al
    imul eax,1000000000
    add SZAM2,eax

    mov eax,SZAM2
    call WriteInt

szorzas:
    Call Crlf
    mov SZAM1,eax
    mov SZAM2,ebx
    imul eax,ebx
    call WriteInt

main endp

end main

1 个答案:

答案 0 :(得分:0)

来自小学

(1 ^ n)*(1 ^ m)= 1 ^(n + m)。因此,如果您有两个32位数字,则需要一个64位数字来处理所有情况。 x86支持将结果放在两个寄存器中,一个得到上半部分,另一个得到下半部分。阅读x86指令集文档。

只要你允许两倍的结果作为操作数,那么最坏的情况数就适合,所以你不必担心标志,只需得到结果。

对于不处理操作数宽度两倍的结果的体系结构。再次,使用小学数学,并将问题分解为多个步骤。您可以将32位数字abcd * efgh分解为16位数,并像手动一样进行乘法运算。 gh * cd,gh * ab,ef * cd,ef * ab。然后进行适当的转换和添加,将这些结果合并到答案中。

如果我有16位十六进制数0xabcd * 0x1234,答案是((0xabcd * 4)<< 0)+((0xabcd * 3)<< 4)+((0xabcd * 2)&lt ;< 8)+((* 0xabcd 1) - ;< 12)

你也可以一次做4位或8位或16位,具体取决于你拥有的硬件,或者可以一次做一位(这是你意识到用二进制乘法非常简单,你或者将数字移动并添加或者你不要)。这可以扩展到你想要的宽度,1百万位数* 1百万位数= 200万位数。只需要进行较小的乘法和转换。

这就是我们在小学时所做的事情,在底部一次拿一位数将它与顶部相乘并将其移到一些地方。您可以使用移位和添加在软件(大多数语言)中实现此功能,或者如果您有硬件乘法,则可以在某些容量中使用它。