Loops/With multiple ranges

You are encouraged to solve this task according to the task description, using any language you may know.
Some languages allow multiple loop ranges, such as the PL/I example (snippet) below.

                                       /* all variables are DECLARED as integers. */
          prod=  1;                    /*start with a product of unity.           */
           sum=  0;                    /*  "     "  "   sum    " zero.            */
             x= +5;
             y= -5;
             z= -2;
           one=  1;
         three=  3;
         seven=  7;
                                       /*(below)  **  is exponentiation:  4**3=64 */
           do j=   -three  to     3**3        by three   ,
                   -seven  to   +seven        by   x     ,
                      555  to      550 - y               ,
                       22  to      -28        by -three  ,
                     1927  to     1939                   ,
                        x  to        y        by   z     ,
                    11**x  to    11**x + one;
                                                        /* ABS(n) = absolute value*/
           sum= sum + abs(j);                           /*add absolute value of J.*/
           if abs(prod)<2**27 & j¬=0  then prod=prod*j; /*PROD is small enough & J*/
           end;                                         /*not 0, then multiply it.*/
                     /*SUM and PROD are used for verification of J incrementation.*/
         display (' sum= ' ||  sum);                    /*display strings to term.*/
         display ('prod= ' || prod);                    /*   "       "     "   "  */


Task

Simulate/translate the above PL/I program snippet as best as possible in your
language,   with particular emphasis on the   do   loop construct.

The   do   index must be incremented/decremented in the same order shown.

If feasible, add commas to the two output numbers (being displayed).

Show all output here.

      A simple PL/I   DO  loop  (incrementing or decrementing)  has the construct of:
 
            DO variable = start_expression    {TO ending_expression]       {BY increment_expression} ;
                 ---or---
            DO variable = start_expression    {BY increment_expression}    {TO ending_expression]    ;  
 
      where it is understood that all expressions will have a value.  The  variable  is normally a 
      scaler variable,  but need not be  (but for this task, all variables and expressions are declared
      to be scaler integers).   If the   BY   expression is omitted,  a   BY   value of unity is used.
      All expressions are evaluated before the   DO   loop is executed,  and those values are used
      throughout the   DO   loop execution   (even though, for instance,  the value of   Z   may be
      changed within the   DO   loop.    This isn't the case here for this task.  
 
      A multiple-range   DO   loop can be constructed by using a comma (,) to separate additional ranges
      (the use of multiple   TO   and/or   BY   keywords).     This is the construct used in this task.
 
      There are other forms of   DO   loops in PL/I involving the  WHILE  clause,  but those won't be 
      needed here.    DO  loops without a   TO   clause might need a   WHILE   clause  or some other 
      means of exiting the loop  (such as  LEAVE,  RETURN,  SIGNAL,  GOTO,  or  STOP),  or some other 
      (possible error) condition that causes transfer of control outside the  DO  loop.
 
      Also, in PL/I, the check if the   DO   loop index value is outside the range is made at the 
      "head"  (start)  of the   DO  loop,  so it's possible that the   DO   loop isn't executed,  but 
      that isn't the case for any of the ranges used in this task. 
 
      In the example above, the clause:                    x    to y       by z     
      will cause the variable   J   to have to following values  (in this order):  5  3  1  -1  -3  -5
 
      In the example above, the clause:                 -seven  to +seven  by x  
      will cause the variable   J   to have to following values  (in this order):  -7  -2   3  


Related tasks

   Loop over multiple arrays simultaneously
   Loops/Break
   Loops/Continue
   Loops/Do-while
   Loops/Downward for
   Loops/For
   Loops/For with a specified step
   Loops/Foreach
   Loops/Increment loop index within loop body
   Loops/Infinite
   Loops/N plus one half
   Loops/Nested
   Loops/While
   Loops/with multiple ranges
   Loops/Wrong ranges


 
/* ARM assembly Raspberry PI  */
/*  program loopnrange.s   */
 
/* REMARK 1 : this program use routines in a include file 
   see task Include a file language arm assembly 
   for the routine affichageMess conversion10 
   see at end of this program the instruction include */
/*********************************/
/* Constantes                    */
/*********************************/
.equ STDOUT, 1     @ Linux output console
.equ EXIT,   1     @ Linux syscall
.equ WRITE,  4     @ Linux syscall
 
/*********************************/
/* Initialized data              */
/*********************************/
.data
szMessResult:      .ascii ""                    @ message result
sMessValeur:       .fill 11, 1, ' '
szCarriageReturn:  .asciz "\n"
/*********************************/
/* UnInitialized data            */
/*********************************/
.bss 
iSum:                      .skip 4         @ this program store sum and product in memory
iProd:                     .skip 4         @ it is possible to use registers r2 and r11
/*********************************/
/*  code section                 */
/*********************************/
.text
.global main 
main:                                       @ entry of program
    ldr r0,iAdriProd
    mov r1,#1
    str r1,[r0]                             @ init product
    ldr r0,iAdriSum
    mov r1,#0
    str r1,[r0]                             @ init sum
 
    mov r5,#5                               @ x
    mov r4,#-5                              @ y
    mov r6,#-2                              @ z
    mov r8,#1                               @ one
    mov r3,#3                               @ three
    mov r7,#7                               @ seven
 
                                            @ loop one
    mov r0,#3
    mov r1,#3
    bl computePow                           @ compute 3 pow 3
    mov r10,r0                              @ save result
    mvn r9,r3                               @ r9 = - three
    add r9,#1
1: 
    mov r0,r9
    bl computeSumProd
    add r9,r3                               @ increment with three
    cmp r9,r10
    ble 1b
                                            @ loop two
    mvn r9,r7                               @ r9 = - seven
    add r9,#1
2: 
    mov r0,r9
    bl computeSumProd
    add r9,r5                               @ increment with x
    cmp r9,r7                               @ compare to seven
    ble 2b
 
                                            @ loop three
    mov r9,#550
    sub r10,r9,r4                           @ r10 = 550 - y
    mov r9,#555
3: 
    mov r0,r9
    bl computeSumProd
    add r9,#1
    cmp r9,r10
    ble 3b
                                            @ loop four
    mov r9,#22
4: 
    mov r0,r9
    bl computeSumProd
    sub r9,r3                               @ decrement with three
    cmp r9,#-28
    bge 4b
                                            @ loop five
    mov r9,#1927
    ldr r10,iVal1939
5: 
    mov r0,r9
    bl computeSumProd
    add r9,#1
    cmp r9,r10
    ble 5b
                                            @ loop six
    mov r9,r5                               @ r9 = x
    mvn r10,r6                              @ r10 = - z
    add r10,#1
6: 
    mov r0,r9
    bl computeSumProd
    sub r9,r10
    cmp r9,r4
    bge 6b
                                            @ loop seven
    mov r0,r5
    mov r1,#11
    bl computePow                           @ compute 11 pow x
    add r10,r0,r8                           @ + one
    mov r9,r0
7: 
    mov r0,r9
    bl computeSumProd
    add r9,#1
    cmp r9,r10
    ble 7b
                                            @ display result
    ldr r0,iAdriSum
    ldr r0,[r0]
    ldr r1,iAdrsMessValeur                  @ signed conversion value
    bl conversion10S                        @ decimal conversion
    ldr r0,iAdrszMessResult
    bl affichageMess                        @ display message
    ldr r0,iAdrszCarriageReturn
    bl affichageMess                        @ display return line
    ldr r0,iAdriProd
    ldr r0,[r0]
    ldr r1,iAdrsMessValeur                  @ conversion value
    bl conversion10S                        @ signed decimal conversion
    ldr r0,iAdrszMessResult
    bl affichageMess                        @ display message
    ldr r0,iAdrszCarriageReturn
    bl affichageMess                        @ display return line
 
 
100:                                        @ standard end of the program 
    mov r0, #0                              @ return code
    mov r7, #EXIT                           @ request to exit program
    svc #0                                  @ perform the system call
 
iAdrsMessValeur:          .int sMessValeur
iAdrszMessResult:         .int szMessResult
iAdrszCarriageReturn:     .int szCarriageReturn
iVal1939:                 .int 1939
/******************************************************************/
/*     compute the sum and prod                         */ 
/******************************************************************/
/* r0 contains the number  */
computeSumProd:
    push {r1-r4,lr}             @ save  registers 
    asr r1,r0,#31
    eor r2,r0,r1
    sub r2,r2,r1                @ compute absolue value
    //vidregtit somme
    ldr r3,iAdriSum             @ load sum
    ldr r1,[r3]
    add r1,r2                   @ add sum
    str r1,[r3]                 @ store sum
    cmp r0,#0                   @ j = 0 ?
    beq 100f                    @ yes
    ldr r3,iAdriProd
    ldr r1,[r3]
    asr r2,r1,#31               @ compute absolute value of prod
    eor r4,r1,r2
    sub r2,r4,r2
    cmp r2,#1<<27               @ compare 2 puissance 27
    bgt 100f
    mul r1,r0,r1
    str r1,[r3]                 @ store prod
100:
    pop {r1-r4,lr}              @ restaur registers
    bx lr                       @ return
iAdriSum:                .int iSum
iAdriProd:               .int iProd
/******************************************************************/
/*     compute pow                         */ 
/******************************************************************/
/* r0 contains pow  */
/* r1 contains number */
computePow:
    push {r1-r2,lr}             @ save  registers 
    mov r2,r0
    mov r0,#1
1:
    cmp r2,#0
    ble 100f
    mul r0,r1,r0
    sub r2,#1
    b 1b
100:
    pop {r1-r2,lr}              @ restaur registers
    bx lr                       @ return
/***************************************************/
/*      ROUTINES INCLUDE                           */
/***************************************************/
.include "../affichage.inc"
 