正确地对数组求和

时间:2017-03-26 17:14:38

标签: assembly masm irvine32

我正在使用MASM& Irvine 32位汇编,我有阵列A,B,C,我在执行A + B = C时堆叠,将数组A的每个[i]项与数组B相加并写入数组C.

例如,

 arrA 1, 2, 4, 1
 +
 arrB 2, 1, 1, 3 
 =
 arrC 3, 3, 5, 4

我尝试使用指针,但我有00,00,00,0F输出。

不要注意StrHex_MY程序,它会在输出数组上进行测试。

代码:


.586
.model flat, stdcall
ExitProcess PROTO, dwExitCode:DWORD

include \Irvine\Irvine32.inc
includelib \Irvine\kernel32.lib
includelib \Irvine\user32.lib
include module.inc

.data
  CaptionGreet BYTE "Test me", 0

  arrA DWORD 1, 2, 4, 1 
  arrB DWORD 2, 1, 1, 3 
  arrC DWORD 0, 0, 0, 0

  toOut DB 64 dup(?)

.code

main PROC

    mov edi, OFFSET arrA ; Address of arrA
    mov esi, OFFSET arrB ; Address of arrB

    mov eax, 0 ; Register with result

    mov ecx, LENGTHOF arrA ; Lenght of arrays

    L1:
        add eax, [edi] ; Add current arrA element to eax
        add eax, [esi] ; Add current arrB element to eax

        add edi, TYPE arrA ; Move pointer to the next arrA element
        add esi, TYPE arrB ; Move pointer to the next arrB element

        mov arrC, eax ; Move current eax value to arrC

        loop L1

    ; Converting result to HEX toOut. Don't pay attention to this part
    ; ----
    push OFFSET toOut
    push OFFSET arrC
    push 256
    call StrHex_MY
    ; ---

    ; Output result
    INVOKE MessageBoxA, 0, ADDR toOut, ADDR CaptionGreet, 0
    INVOKE ExitProcess,0

main ENDP
END main

2 个答案:

答案 0 :(得分:0)

我想您要将arrA的每个项目添加到其arrB的对应项目中,并将其存储到arrC的对应项目中。所以

add eax, [edi] ; Add current arrA element to eax

错了。你必须"重新初始化" EAX项目:

mov eax, [edi] ; Copy current arrA element to eax

你需要第三个指向arrC的指针。现在,您将结果重复存储到arrC的第一项。我已选择EBX作为第三指针。

INCLUDE Irvine32.inc

.data
  CaptionGreet BYTE "Test me", 0

  arrA DWORD 1, 2, 4, 1
  arrB DWORD 2, 1, 1, 3
  arrC DWORD 0, 0, 0, 0

  toOut DB 64 dup(?)

.code

main PROC

    mov edi, OFFSET arrA    ; Address of arrA
    mov esi, OFFSET arrB    ; Address of arrB
    mov ebx, Offset arrC    ; Address of arrC

    mov eax, 0              ; Register with result

    mov ecx, LENGTHOF arrA  ; Length of arrays

    L1:
        mov eax, [edi]      ; Copy current arrA element to eax
        add eax, [esi]      ; Add current arrB element to eax

        add edi, TYPE arrA  ; Move pointer to the next arrA element
        add esi, TYPE arrB  ; Move pointer to the next arrB element

        mov [ebx], eax      ; Move current eax value to current arrC element
        add ebx, TYPE arrC  ; Move pointer to the next arrC element

        loop L1

    mov esi, OFFSET arrC
    mov ecx, 4
    mov ebx, 4
    call DumpMem


    INVOKE ExitProcess,0

main ENDP

END main

答案 1 :(得分:0)

我还改进了@rkhb所回答的内容,所以现在它不仅执行arrA到相应的arrB,而且还可以使用Carry标志。因此,如果我们想要执行多精度加法运算,我们需要将数字表示为数组并使用进位标志。

在互联网上没有找到关于它的大量信息,所以如果需要,可以在这里:


.586
.model flat, stdcall
ExitProcess PROTO, dwExitCode:DWORD

include \Irvine\Irvine32.inc
includelib \Irvine\kernel32.lib
includelib \Irvine\user32.lib
include module.inc

.data
  CaptionGreet BYTE "Last >> Last
  arrA DWORD 80010001h, 80020001h, 80030001h
  arrB DWORD 80000001h, 80000001h, 80000001h
  arrC DWORD 0, 0, 0

  toOut DB 64 dup(?)

.code

main PROC

    mov edi, OFFSET arrA    ; Address of arrA
    mov esi, OFFSET arrB    ; Address of arrB
    mov ebx, Offset arrC    ; Address of arrC

    mov eax, 0              ; Register with result
    pushad
    clc ; Make Carry flag zero

    mov ecx, LENGTHOF arrA  ; Length of arrays

    L1:
        pushfd ; Restore Carry flag
        mov eax, [edi]      ; Copy current arrA element to eax
        popfd
        adc eax, [esi]      ; Add current arrB element to eax, if Carry flag is non-zero, it is also added
        pushfd ; Push Carry flag to FLAGS register

        add edi, TYPE arrA  ; Move pointer to the next arrA element
        add esi, TYPE arrB  ; Move pointer to the next arrB element

        mov [ebx], eax      ; Move current eax value to current arrC element
        add ebx, TYPE arrC  ; Move pointer to the next arrC element
        popfd
        loop L1 

    ; Convert result to HEX toOut
    push OFFSET toOut
    push OFFSET arrC
    push 480
    call StrHex_MY

    ; Output result
    INVOKE MessageBoxA, 0, ADDR toOut, ADDR CaptionGreet, 0
    INVOKE ExitProcess,0

main ENDP
END main