How to move and display array values from one to another in Assembly Language? - arrays

I am trying to move the values in Array1 to Array2, and then display them. I have been working on this and could not figure it out at all. Would anyone please help me? Thanks
INCLUDE Irvine32.inc
INCLUDE macros.inc
.data
Array1 DWord 2,4,6,8,10
Array2 DWord 5 Dup(0)
.code
main PROC
mov edx, OFFSET Array1
mov esi, OFFSET Array2
mov ecx, LENGTHOF Array1
mov eax, 0
Call Dumpregs
Call Dumpregs
L1:
mWrite "Hello"
Call CRLF
Loop L1
Call Dumpregs
L2:
mov eax, [edx]
mov [esi], eax
add esi, 4
add edx, 4
Loop L2
exit
main ENDP
END main

Your L2 loop cannot produce the desired result since the preceding code wiped ECX clean (You used loop L1). To copy the array you need to re-initialize ECX. Also it's best to setup the pointers EDX and ESI close to this L2 loop because perhaps there is a risk of them being modified by all those preceding (macro)calls!
mov edx, OFFSET Array1
mov esi, OFFSET Array2
mov ecx,5
L2:
mov eax,[edx]
mov [esi],eax
add esi, 4
add edx, 4
loop L2

Related

how to display the count in MASM?

this is my code for a MASM assignment, the assignment is:
Write an application that does the following:
Declare a 32-bit integer array with 50 elements with uninitialized values
Fill the 32-bit array with 50 random integers
Loop through array, and display each value, and count the number of negative values
After final loop finishes, display the count
I have it doing everything but displaying the count of negative numbers. If anyone can tell me where I am wrong that would be super helpful I have been working on this for some time.
INCLUDE Irvine32.inc
.data
myArray SWORD 50 DUP(?)
count DWORD 0
.code
main proc
call randomize
mov esi, offset myArray
mov ecx, lengthof myArray
L1:
call Random32
call WriteInt
call Crlf
mov [esi], eax
add esi, 4
loop L1
mov eax, offset myArray
mov esi, lengthof myArray
L2:
cmp dword ptr[esi], 0
jge L3
DWORD count
L3:
add esi, 4
loop L2
mov eax, count
call WriteDec
call Crlf
exit
main ENDP
END main

Array Bubble Sort in Assembly Language

Problem is that why is only sorting the last element and then putting 5 on every index?
I am posting for the first time so I apologize if my question is unclear.
arr BYTE 5,4,3,2,1
arr1 BYTE 5 DUP(?)
temp BYTE ?
.code
main PROC
mov ecx,LENGTHOF arr
mov esi,Offset arr
mov edi,offset arr+1
L1:
mov al,[esi]
mov edx,ecx
mov ecx,4
L2:
mov bl,[edi]
cmp al,bl
JG L3
jmp L5
L3:
mov temp,al
mov [esi],bl
;mov dl,temp
mov [edi],al
inc edi
L5:
loop L2
mov ecx,edx
inc esi
loop L1
;Printing my array
mov ecx,LENGTHOF arr
mov al,arr[0]
CALL dumpRegs
mov al,arr[1]
CALL dumpRegs
mov al,arr[2]
CALL dumpRegs
mov al,arr[3]
CALL dumpRegs
CALL dumpRegs
exit
main ENDP
END main
Problem is that why is only sorting the last element and then putting 5 on every index?
Your L2 InnerLoop works exclusively with the 1st array element since, once it is loaded in AL, you don't advance the pointer in ESI. And because this particular value happens to be the greatest value in the array, it gets stored everywhere.
Your L2 InnerLoop also works with a fixed count of 4 where it should be working with a count of CurrentOuterLoopCount - 1.
The correct solution does not need the 2 different pointer registers. The array elements that are to be compared are always adjacent to each other and so a simple offset of +1 will do the trick.
This is a working BubbleSort. Find out how it works, don't just copy it!
arr BYTE 5,4,3,2,1
.code
main PROC
mov ecx, LENGTHOF arr
sub ecx, 1
jbe Done ; Array is empty or has but 1 element
OuterLoop:
mov edx, ecx ; 5 elements means 4 comparisons
mov esi, Offset arr
InnerLoop:
mov al, [esi]
mov bl, [esi+1]
cmp al, bl
jng NoSwap
mov [esi], bl
mov [esi+1], al
NoSwap:
inc esi
dec edx
jnz InnerLoop
dec ecx ; Next time 3 comparisons, then 2, and then 1
jnz OuterLoop
Done:

Assembly How should I increment the array if I want to switch values?

This is being compiled on Visual Studios 2015 with Kip Irvine.
The code is supposed to switch the 1st element with the 2nd element and the 3rd element with the 4th element and so on. It switches the values forward instead of just switching the two values. I added the index register with 2 to skip the 2nd element since it should not be switched. Is there something I am missing? Am I supposed to increment the array index differently or am I putting the wrong values in the wrong registers? Thanks in advance! Please don't just give me the answer.
The output is
Dump of offset 00AD6880
00020000 00050000 00090000 0000000A 0000000C
INCLUDE Irvine32.inc
.data
dwarray dword 0,2,5,9,10,12
.code
main proc
mov ebx, OFFSET dwarray
mov ecx, LENGTHOF dwarray
L1: cmp ebx, ecx
mov eax, [ebx]
mov edx, [ebx+1]
mov [ebx+1], eax
mov [ebx], edx
add ebx, 2
loop L1
; The four instructions below are fixed, the only variable is the name of the array
mov esi,OFFSET dwarray
mov ecx,LENGTHOF dwarray
mov ebx,TYPE dwarray
call DumpMem
call WaitMsg
exit
main ENDP
END main
Your array elements are dword, double word, that means 4 bytes. So, in order to point to the elements you need to increase your pointer by 4 :
dwarray dword 0,2,5,9,10,12
.code
main proc
mov ebx, OFFSET dwarray
mov ecx, 3 ◄■■■ THE ARRAY CONTAINS 6 ELEMENTS, BUT THEY ARE PROCESSED
IN PAIRS, SO THE LOOP SHOULD REPEAT HALF 6 (3).
L1: ;cmp ebx, ecx ◄■■■ UNNECESSARY?
mov eax, [ebx]
mov edx, [ebx+4] ◄■■■ THE NEXT ELEMENT IS 4 BYTES AWAY.
mov [ebx+4], eax ◄■■■ AGAIN, THE NEXT ELEMENT IS 4 BYTES.
mov [ebx], edx
add ebx, 8 ◄■■■ INCREASE BY 8 (THE SIZE OF 2 ELEMENTS PROCESSED).
loop L1

Array access in MASM

I'm having some difficulty with my array accessing in MASM. I've got a very large array and a temp variable like so:
.data
array DWORD 65000 DUP (0)
temp DWORD 0
In my main, I've got this to fill it:
mov esi, offset array
mov edi, 0
mov ecx, 0
fill:
mov [esi], ecx
add esi, 4
inc ecx
cmp ecx, 65000
jl fill
mov esi, offset array ;reset the array location to the start
After, I want to access the array with this loop:
mark:
mov temp, 4 ;get another 4 to temp to move along the array
add esi, temp ;add temp to esi to keep moving
mov edx, [esi] ;access the current value
cmp esi, 20 ;just trying to get first few elements
jmp mark
exit
main ENDP
END main
I always have an access violation error, with the break at the line where I try to access the current value. This occurs on the very first loop as well. Any idea why this is happening? Thanks!
Your code will work to an extent, however:
mark:
mov temp, 4
add esi, temp ;Incrementing before first loop means you miss the first stored value
mov edx, [esi]
cmp esi, 20 ;ESI is the address your are accessing, not a count
jmp mark ;This loop will be infinite

PUSH and POP out of DWORD in Assembly x86

So far I tried several ways to print the values in DWORD, but I only get either the first or last digit, and I would need to print all 5 digits in reverse order.
INCLUDE Irvine32.inc
.data
arr1 DWORD 2, 4, 6, 8, 10
.code
main PROC
mov ecx,4
mov esi,0
L1:
mov eax,arr1[esi]
push eax
sub esi,4
loop L1
mov ecx,4
mov esi,0
L2: pop eax
mov arr1[esi],eax
add esi,4
loop L2
mov esi,OFFSET arr1
mov ecx,4
L3:
mov eax,[esi+ecx*4]
call WriteDec
sub ecx,4
call EndLine
loop L3
call Crlf
exit
main ENDP
END main
Ok, the Stack is LIFO, meaning the last value you pushed onto the stack is the first value popped off, right?
If you do:
push 2
push 4
push 6
push 8
push 10
Then the first value popped off the stack is 10, then 8, then 6, etc. So 10 will get printed first.
We can get rid of a lot of your code, since you just want to print the values in reverse order with pop.
main PROC
mov ecx, 5
mov esi, 0
L1:
push arr1[esi]
add esi, 4 ; add 4 to arr1 pointer
loop L1 ; loop until ecx == 0
mov ecx, 5 ; reset loop counter
L3:
pop eax
call WriteDec
call Crlf
loop L3
call Crlf
call WaitMsg
exit
main ENDP

Resources