Arrays in MASM Assembly (very confused beginner)

16,560

There are more than one way to populate an array and your code is almost working. One way is to use counter in the indirect address so you don't have to modify destination and source array pointers each loop:

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

Of course this code could be modified to fill the array backwards to possibly save couple of bytes like you probably meant to do in your original code. Here is another way that has more compact loop:

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

You should also note that when working with arrays of the same type you can do simple copy very efficiently using repeat prefix with instructions like 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
Share:
16,560

Related videos on Youtube

Xar
Author by

Xar

Updated on June 04, 2022

Comments

  • Xar
    Xar almost 2 years

    I have a pretty basic question: How do you populate arrays in assembly? In high level programming languages you can use a for-loop to set a value to each index, but I'm not sure of how to accomplish the same thing assembly. I know this is wrong, but this is what I have:

    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
    

    Each time the loop runs, ax will be overwritten with the value of the array's index, right? Instead how do I populate darray with the array elements from warray? Any help would be very much appreciated...I'm pretty confused.

  • drivingon9
    drivingon9 over 9 years
    They're not as bad as you make them out to be. They used to be pretty poorly implemented, but on newer architectures (SNB+) they're actually pretty fast. They're not a complete replacement for macro instructions yet, but there are a few cases in which they perform better than hand written assembly.
  • User.1
    User.1 over 9 years
    @drivingon9 Totally agree with you. Write them in the right way (a ridiculous play on words, I suppose) and they will accomplish what few other instructions can do. It just seems that, nowadays, the string instructions have been labeled as generally not cool. Stupid ? Indeed ! But, that's life today.
  • User.1
    User.1 over 9 years
    Lost the editing window time. @drivingon9 plus one for your comment and I edited my answer.
  • Peter Cordes
    Peter Cordes over 4 years
    You need a movzx load and a mov store, not the other way around. movzx only exists with a register destination.
  • Peter Cordes
    Peter Cordes over 4 years
    repne scasb (memchr) and repe cmpsb (memcmp) are only useful for code-size, not performance. Fast-strings and ERMSB microcode only speeds up rep stos and rep movs, not the conditional rep search instruction. They're very slow, like 2 cycles per compare for repe cmpsb, on modern x86 (e.g. Skylake), so about 32x slower than a good SSE2 pcmpeqb for large arrays, not even AVX2. Also not very good for short arrays; they have some startup overhead. lodsd or lodsq without rep is occasionally worth using on Haswell and later (only 2 uops, same as mov-load + add), but others are worse