1

I've got this code, but how would I make it using loops. Basically Its a code that takes the first value in the x array and adds it to the next, saves it to the first value in y, then takes the second value from x and adds it to the third and stores it in the second value in y, and so forth. Then it takes the last value of x and adds it to the first value of x and saves it to the last value of y.

    .data  
    x   sword   10,20,30,-10,-20, -30  
    y   sword   6 dup (?)

    mov     ax,x                                
    add     x+2,ax  
    mov         y,ax

    mov     ax,x+2                              
    add     x+4,ax  
    mov         y+2,ax

    mov     ax,x+4                              
    add     x+6,ax  
    mov         y+4,ax

    mov     ax,x+6                              
    add     x+8,ax  
    mov         y+6,ax

    mov     ax,x+8                              
    add     x+10,ax  
    mov         y+8,ax

    mov     ax,x+10                             
    add     x,ax  
    mov         y+10,ax

2 Answers 2

1

Its a code that takes the first value in the x array and adds it to the next, saves it to the first value in y, then takes the second value from x and adds it to the third and stores it in the second value in y, and so forth. Then it takes the last value of x and adds it to the first value of x and saves it to the last value of y.

This is an ambiguous wording! "adds it to the next" need not automatically imply writing the sum into the X array, just as "saves it to the first value in y" does not necessarily mean that it is the original (before addition) value that goes into the Y array. That is how the unrolled code that you show us does it, but it is not how the pseudo code in @SevaAlekseyev's answer does it, so be careful!

The code snippets in my answer do it like you have shown because the sentence "Then it takes the last value of x and adds it to the first value of x and saves it to the last value of y." seems to tell us just that...

Writing a loop

The simplest solution uses an address register for the X array and another address register for the Y array. If this needs to be code then you can choose between BX, SI, DI, and BP. The 'index' registers SI and DI being the logical choices. Since your array has 6 elements but processing the last element is somewhat special, you could initialize the counter in CX to 1 less, so 5, and then process the last element separately outside of the loop. This will avoid having to insert conditional branches:

  .data  
    x   sword   10, 20, 30, -10, -20, -30  
    y   sword   6 dup (?)

  mov  di, OFFSET y
  mov  si, OFFSET x
  mov  cx, 5
more:
  mov  ax, [si]         ; mov  ax, x
  add  si, 2
  add  [si], ax         ; add  x+2, ax
  mov  [di], ax         ; mov  y, ax
  add  di, 2
  loop more
  mov  ax, [si]         ; mov  ax, x+10
  add  x, ax            ; add  x, ax
  mov  [di], ax         ; mov  y+10, ax

Next is an alternative way that too avoids having to insert conditional branches. Note the extra word at the end of the X array that I'll use for a sixth regular iteration followed by a corrective add onto the first element of the X array. Since we're assuming , why not shorten the code using the lodsw and stosw string primitives:

  .data  
    x   sword   10, 20, 30, -10, -20, -30, ?
    y   sword   6 dup (?)

  mov  di, OFFSET y
  mov  si, OFFSET x
  mov  cx, 6
more:
  lodsw                 ; mov  ax, x
  add  [si], ax         ; add  x+2, ax
  stosw                 ; mov  y, ax
  loop more
  add  x, ax            ; add  x, ax

And next code shows how you could use a single index instead of separate pointers. The index increments by 2 because it is actually an offset in the arrays that hold word-sized elements. This snippet also demonstrates that you don't have to use the loop instruction per se. In code it is fine but don't use loop in 32-bit code where it is a slow instruction:

  .data  
    x   sword   10, 20, 30, -10, -20, -30  
    y   sword   6 dup (?)

  xor  bx, bx           ; Current offset in the arrays
more:
  mov  ax, [x + bx]     ; mov  ax, x
  mov  [y + bx], ax     ; mov  y, ax
  add  bx, 2
  add  [x + bx], ax     ; add  x+2, ax
  cmp  bx, 10           ; Continue for the first 5 word-sized elements
  jb   more
  mov  ax, [x + bx]     ; mov  ax, x+10
  add  x, ax            ; add  x, ax
  mov  [y + bx], ax     ; mov  y+10, ax
Sign up to request clarification or add additional context in comments.

Comments

0

First, to read/write a memory location, you need to use []. [ax] is the memory location at ax, and so on. Works for arrays, too: [x+2] means the second element of x (because they're two bytes each).

Moving on. You can accomplish a loop over array(s) with an index or with running pointers. Let's consider the first.

So you need to run an index (i) from 0 to 5. For each value, you need to assign to y[i] the value of x[1] + x[i+1], with the exception of the last one. You'll need a conditional to take care of the last one.

In Intel, there are two registers specifically designed to be indices - SI and DI. You can address arrays with them premultiplied - constructs like [array+SI*2].

In order to do a loop, you need a conditional jump back: if the index is less than array size, execute the loop again.

So, in pseudocode, deliberately using variable names instead of registers:

i=0
Loop:
copy x[i] into y[i] (more than one command in assembly)
if i = array_size-1 then add x[0] to y[i] (conditional jump here)
else add x[i+1] to y[i]

increment i
if i = array_size then jump to loop

1 Comment

You can address arrays with them premultiplied - constructs like [array+SI*2]. - Not for 16-bit address-size. (Why don't x86 16-bit addressing modes have a scale factor, while the 32-bit version has it?). Increment the register by 2 intead.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.