1

Hey I need to make a program that loops through an array (1,2,3,4,5,6,7,8,9,10) and exchanges the element ‘i’ with element ‘i+5’ when ‘i' is under 4 When the program ends, the new array has the following values 6,7,8,9,10,1,2,3,4,5

and right now I have it looping through the array

    .386
.model flat,stdcall
.stack 4096
ExitProcess proto,dwExitCode:dword
WriteDec PROTO
Crlf PROTO
DumpRegs PROTO
.data
arrayB WORD 1,2,3,4,5,6,7,8,9,10
.code
main proc
mov eax,0

mov edi,OFFSET arrayB   ; address of arrayB
mov ecx,LENGTHOF arrayB ; loop counter

mov ax,0    ; zero the accumulator

L1:
mov ax,[edi]    ; mov current edi value from array into ax
xchg arrayB, ax ;change the current ax register with the value in arrayB
add edi,TYPE arrayB ; point to next integer

    loop L1

    call DumpRegs
    call WriteDec
    call crlf
    invoke ExitProcess,0
main endp
end main

But Im having trouble actually a) telling when the loop is under 4, and b) replacing the values correctly. Any help would be greatly appreciated

Edit: I do know I can use "cmp" to compare the ecx register

Code Gorilla
  • 43
  • 1
  • 6

2 Answers2

2

Your task description is inconsistent; you say the array should be 6,7,8,9,10,1,2,3,4,5 at the end, and that calls for exchanging all elements with index under 5 (elements 0 to 4), not under 4.

The LOOP command (which is not a good idea, but that's beside the point) uses ECX as an implicit counter. If ECX is nonzero, it decrements and jumps to the label, if it's zero, it doesn't. So you're looping for exactly LENGTHOF arrayB times; that's wrong, you want to loop for half that.

Also, the XCHG command is wrong. The destination for the exchange is not at arrayB, it's at the current index + 5. You figure out how to fix that.

Also, once you exchange ax with the index+5'th element, you still need to write the retrieved value of the index+5'th element back into the index'th position.

Ped7g
  • 16,236
  • 3
  • 26
  • 63
Seva Alekseyev
  • 59,826
  • 25
  • 160
  • 281
  • XCHG with memory is also extremely slow: implicit `lock` prefix. If you're going to point out that [LOOP is slow](http://stackoverflow.com/questions/35742570/why-is-the-loop-instruction-slow-couldnt-intel-have-implemented-it-efficiently), you should def point that out, too. – Peter Cordes Nov 03 '16 at 02:45
  • Well I managed to get it counting 6,7,8,9,10 but I think it's still off – Code Gorilla Nov 03 '16 at 18:58
  • 1
    Do you know how to debug? Single-step through the program, watch register values on every step? If not, find out how right away. – Seva Alekseyev Nov 03 '16 at 20:22
1

You are using edi to point to the elements of the array and store them in ax, one solution will be to use esi to point to the element+5 and store it in bx, then move bx into edi and move ax into esi (by the way, the loop should repeat half-array-length times) :

    .386
.model flat,stdcall
.stack 4096
ExitProcess proto,dwExitCode:dword
WriteDec PROTO
Crlf PROTO
DumpRegs PROTO
.data
arrayB WORD 1,2,3,4,5,6,7,8,9,10
.code
main proc
;mov eax,0              ;◄■■ UNNECESSARY.

mov edi,OFFSET arrayB   ; address of arrayB
mov ecx,5               ;◄■■ 10 ÷ 2 ("when ‘i' is under 4").

;mov ax,0               ;◄■■ UNNECESSARY.

L1:
mov ax,[edi]            ; mov current edi value from array into ax
mov esi,edi
add esi,TYPE arrayB * 5 ;◄■■ ELEMENT "I+5".
mov bx,[esi]            ;◄■■ BX = "I+5".
mov [edi],bx            ;◄■■ EXCHANGE ONE REGISTER.
mov [esi],ax            ;◄■■ EXCHANGE THE OTHER REGISTER.
add edi,TYPE arrayB     ; point to next integer
    loop L1
;----------------------------------------------
    mov edi, OFFSET arrayB
    mov ecx, LENGTHOF arrayB
DISPLAY_ARRAY:
    xor  eax, eax
    mov  ax, [edi]
    call WriteDec
    add edi,TYPE arrayB     ; point to next integer
    loop DISPLAY_ARRAY
;----------------------------------------------
    call DumpRegs
    call WriteDec
    call crlf
    invoke ExitProcess,0
main endp
end main

Edited the answer to add loop to display the array elements.

  • Hey thanks, but when I used the code it's saying "1>Array.asm(1): error A2044: invalid character in file" Dont know why it's doing that now – Code Gorilla Nov 03 '16 at 20:09
  • I did, they're gone but it's still complaining? – Code Gorilla Nov 03 '16 at 20:13
  • yeah, everything is gone except for the code and it still is complaining? Edit:ok now I removed everything, it's just a white screen, and it still has issues saying there's an invalid character – Code Gorilla Nov 03 '16 at 20:21
  • Yeah, now my code, before any changes, is saying "1>Array.asm(1): error A2044: invalid character in file", when I ran your code Visual studio asked about some confirmation about ASCII? – Code Gorilla Nov 03 '16 at 20:46
  • Ok, I managed to fix it, but my output window is showing something like "3572629509"? Shouldn't it be displaying 6,7,8,9,10,1,2,4,5? Edit:Sorry for asking so many questions, I just want to make sure a) I understand whats going on and b) it works. – Code Gorilla Nov 03 '16 at 20:52
  • @CodeGorilla, what I'm doing is to **watch** the array variable, not displaying it. – Jose Manuel Abarca Rodríguez Nov 03 '16 at 21:03
  • So, it watches it, and it order to display it, in the loop all I need to do is just mov the variable into the appropriate register? – Code Gorilla Nov 03 '16 at 21:09
  • Yeah, so I have the normal array (1,2,3,4,5,6,7,8,9,10) and the loop was supposed to make the array now (6,7,8,9,10,1,2,3,4,5) – Code Gorilla Nov 03 '16 at 21:14
  • Yeah, so would I just need to mov the values into a register and call writeDec to print them out? – Code Gorilla Nov 03 '16 at 21:19
  • @CodeGorilla, the array contains 10 elements, so you need to move each element into `ax` register and call WriteDec (10 times). That's what my new loop does. – Jose Manuel Abarca Rodríguez Nov 03 '16 at 21:21
  • 1
    wait, but it's still only printing 1,2,3,4,5? ohh wait I see you edited the above code. – Code Gorilla Nov 03 '16 at 21:23
  • thank you so much, Im seeing where my issues came up from my original code, compared to this – Code Gorilla Nov 03 '16 at 21:36
  • 1
    Lol, I assumed I couldn't mostly because I have no reputation, surprised that it works. Thanks again – Code Gorilla Nov 03 '16 at 21:44