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
Related
can anyone help me with this problem, I'm new to assembly language and somewhat stuck on what to do next. Here's the code:
.data
evenStart dword 11h
oddStart dword 20h
darray dword 15 dup (?)
.code
main PROC
mov esi, OFFSET darray
xor ecx, ecx
L1:
mov ebx, OFFSET evenStart
test cl,1
jz iseven
mov ebx, OFFSET oddStart
iseven:
mov eax, [ebx]
inc dword ptr [ebx]
mov dword ptr [esi + 4*ecx],eax
inc ecx
cmp ecx,15
jb L1
exit
main ENDP
END main
So the project requires me to fill the uninitilized array, which I did. But then it also ask me to sort through this array in descending order and then put the middle elements of the array into the eax register and call DumpRegs. This is the part where I got stuck in. Any help on how to proceed would be great. Thank you!
Next Bubble Sort uses nested loops. Because your array has 15 elements, the outer loop can do 14 comparisons during its 1st iteration. With each iteration of the outer loop it has to do 1 comparison less because the smallest element has bubbled towards the end of the array.
mov ebx, 15-1 ; Outer loop iteration count
OuterLoop:
mov esi, offset darray
mov ecx, ebx ; Inner loop iteration count
InnerLoop:
lodsd
mov edx, [esi]
cmp eax, edx
jge Skip
mov [esi-4], edx ; Swap these 2 elements
mov [esi], eax
Skip:
dec ecx
jnz InnerLoop
dec ebx
jnz OuterLoop
The unsorted array:
11h, 20h, 12h, 21h, 13h, 22h, 14h, 23h, 15h, 24h, 16h, 25h, 17h, 26h, 18h
The sorted array:
26h, 25h, 24h, 23h, 22h, 21h, 20h, 18h, 17h, 16h, 15h, 14h, 13h, 12h, 11h
In this array with an odd number of elements (15), the element indexes range from 0 to 14. There is a true middle element at index 7.
I have to sort an array in descending order using parameters on the stack to an array and an array size. I passed the size by value at ebp+12 and the array by reference at ebp+8.
I know the code is kind of all over the place, but I'm just trying to get to something that works and I can try to clean it up from there.
I've been debugging and it seems to iterate through as I want it to, but my array isn't being sorted. I've been banging my head against this for hours, so any guidance would be greatly appreciated.
The pseudo-code algorithm I'm trying to follow is:
for(k=0, k<arrlength-1,k++)
I=K
for(J=k+1,J<arrlength,J++)
if(arr[j]>arr[i])
I=J
xchg(arr[k], arr[i])
And this is my attempt to implement it in x86 assembly:
;------------------------------------------------
sortlist PROC
;Sorts an array of specified size into descending order
;Receives: DWORD request value, address of an array
;Returns: array of size request, sorted in descending order
;------------------------------------------------
.data
first DWORD ?
next DWORD ?
.code
push ebp
mov ebp, esp
mov ecx, [ebp+12]
mov edi, [ebp+8]
mov eax, 0
mov ebx, 0
mov edx, 0
mov esi, 0
dec ecx ;loop for array length - 1
L1:
add edi, ebx ;ebx = 0 first loop, 4 all remaining loops
mov eax, [edi] ;get the value of the first element
mov first, edi ;store address of first element in first
mov next, edi
push ecx
push edi
L2:
add edi, 4 ;move to next element in array
mov edx, [edi] ;set value of next element to edx
cmp [next], edx ;compare element to next element
jg nxt
mov next, edi ;If less than, move address of greater to next
nxt:
loop L2
mov eax,[next] ;move values pointed to by 1st & next to regs
mov ebx,[first]
mov [first],eax ;move values(swapped) to addresses
mov [next],ebx
mov ebx,4
pop edi
pop ecx
loop L1
pop ebp
ret 8
sortlist ENDP
I'm trying to print the contents of an array by using assembly language as below.
I could compile the code, but I could not run it.
How should I fix the code to print the contents of an array?
TITLE arrayFill_example (arrayFill_ex.asm)
INCLUDE Irvine32.inc
.data
count = 5
array DWORD count DUP(?)
arraySize = ($ - array) / 4
.code
; saves the general-purpose registers, retrieves the parameters, and fills the array
ArrayFill PROC
push ebp
mov ebp,esp
pushad ; save registers
mov esi,[ebp+12] ; offset of array
mov ecx,[ebp+8] ; array length
cmp ecx,0 ; ECX == 0?
je L2 ; yes: skip over loop
L1:
mov eax,10000h ; get random 0-FFFFh
call RandomRange ; from the link library
mov [esi],ax ; insert value in array
add esi,TYPE WORD ; move to next element
loop L1
L2: popad ; restore registers
pop ebp
ret 8 ; clean up the stack
ArrayFill ENDP
main PROC
push OFFSET array ; passed by reference
push count ; passed by value
call ArrayFill
; for showing array contents
mov eax, 0
mov esi, array
mov ecx, arraySize
L1:
mov eax, array[esi * TYPE array]
call WriteInt
call Crlf
add esi, 4
loop L1
exit
main ENDP
END main
Specifically this part is not working for me...
; for showing array contents
mov eax, 0
mov esi, array
mov ecx, arraySize
L1:
mov eax, array[esi * TYPE array]
call WriteInt
call Crlf
add esi, 4
loop L1
Problem 1
array DWORD count DUP(?)
With this definition the array contains dwords. But your program just fills the array with words using:
mov [esi],ax ; insert value in array
add esi,TYPE WORD ; move to next element
Better write:
mov [esi], eax ; insert value in array
add esi, 4 ; move to next element
Problem 2
mov esi, array
...
mov eax, array[esi * TYPE array]
These lines are redundantly referring to the array. That's adding a pointer to a pointer, giving the wrong address! (Or actually, mov esi, array loaded the first element, not the address, because that's how MASM syntax works.)
mov esi, OFFSET array gives you the address in esi. From there, [esi] is the first element, array[esi] is similar to C array[ (intptr_t)array ] (but just a byte offset without scaling by the element size). The resulting address is unlikely to be valid.
Just use one or the other, indexing with small integers, or a pointer increment. Getting a pointer into a register is usually good, as in:
mov esi, OFFSET array
mov ecx, arraySize
L1:
mov eax, [esi]
call WriteInt
call Crlf
add esi, 4
loop L1
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
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