1. ホーム
  2. arrays

[解決済み] MASMアセンブリの配列 (非常に混乱している初級者)

2022-02-16 13:02:03

質問

かなり基本的な質問なのですが アセンブリでどのように配列に値を入れるのですか?高レベルのプログラミング言語では、各インデックスに値を設定するためにforループを使用することができますが、私は同じことをアセンブリを達成する方法がわからないです。私はこれが間違っていることを知っているが、これは私が持っているものです。

ExitProcess PROTO
.data
warray WORD 1,2,3,4
darray DWORD ?

.code
main PROC
mov edi, OFFSET warray
mov esi, OFFSET darray
mov ecx, LENGTHOF warray


L1:
mov ax, [edi]          ;i want to move a number from warray to ax
movzx esi,ax           ;i want to move that number into darray...
add edi, TYPE warray   ;this points to the next number?

    loop L1 

    call ExitProcess
main ENDP
END

ループが実行されるたびに、axは配列のインデックスの値で上書きされますよね?そうではなく、warrayからdarrayに配列の要素を入れるにはどうしたらいいのでしょうか?どんな助けでも非常に感謝します...私はかなり混乱しています。

どのように解決するのですか?

配列に値を入れる方法は複数あり、あなたのコードはほとんど動作しています。1つは、間接アドレスにカウンターを使用する方法で、これにより、ループのたびに出力先と出力元の配列ポインターを変更する必要がなくなります。

ExitProcess PROTO
.data
    warray WORD 1,2,3,4
    darray DWORD 4 dup (?) ; 4 elements

.code
main PROC
    mov edi, OFFSET warray
    mov esi, OFFSET darray
    xor ecx, ecx                ; clear counter
L1:
    mov ax, [edi + ecx * 2]     ; get number from warray
    movzx [esi + ecx * 4], ax   ; move number to darray
    inc ecx                     ; increment counter
    cmp ecx, LENGTHOF warray
    jne L1 

    call ExitProcess
main ENDP
END

もちろん、このコードは、あなたが元のコードで意図したように、おそらく数バイトを節約するために逆方向の配列を埋めるように修正することができます。以下は、よりコンパクトなループを持つ別の方法です。

ExitProcess PROTO
.data
    warray WORD 1,2,3,4
    darray DWORD 4 dup (?) ; 4 elements

.code
main PROC
    mov edi, OFFSET warray
    mov esi, OFFSET darray
    mov ecx, LENGTHOF warray - 1    ; start from end of array
L1:
    mov ax, [edi + ecx * 2]     ; get number from warray
    movzx [esi + ecx * 4], ax   ; move number to darray
    loop L1 

    ; get and set element zero separately because loop terminates on ecx = 0:
    mov ax, [edi]
    movzx [esi], ax

    call ExitProcess
main ENDP
END

また,同じ型の配列を扱う場合,repeat prefix を使って,次のような命令で非常に効率的に単純なコピーを行うことができることに注意する必要があります. MOVSD :

ExitProcess PROTO
.data
    array1 DWORD 1,2,3,4
    array2 DWORD 4 dup (?)

.code
main PROC
    mov esi, OFFSET array1      ; source pointer in esi
    mov edi, OFFSET array2      ; destination in edi
    mov ecx, LENGTHOF array1    ; number of dwords to copy
    cld                         ; clear direction flag so that pointers are increasing
    rep movsd                   ; copy ecx dwords
    call ExitProcess
main ENDP
END