Arrays in MASM Assembly (very confused beginner)
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
Related videos on Youtube
Xar
Updated on June 04, 2022Comments
-
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 over 9 yearsThey'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 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 over 9 yearsLost the editing window time. @drivingon9 plus one for your comment and I edited my answer.
-
Peter Cordes over 4 yearsYou need a
movzx
load and amov
store, not the other way around.movzx
only exists with a register destination. -
Peter Cordes over 4 years
repne scasb
(memchr) andrepe cmpsb
(memcmp) are only useful for code-size, not performance. Fast-strings and ERMSB microcode only speeds uprep stos
andrep movs
, not the conditional rep search instruction. They're very slow, like 2 cycles per compare forrepe cmpsb
, on modern x86 (e.g. Skylake), so about 32x slower than a good SSE2pcmpeqb
for large arrays, not even AVX2. Also not very good for short arrays; they have some startup overhead.lodsd
orlodsq
without rep is occasionally worth using on Haswell and later (only 2 uops, same as mov-load + add), but others are worse