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 AARCH64 Raspberry PI 3B */
/*  program loopnrange64.s   */
 
/*******************************************/
/* Constantes file                         */
/*******************************************/
/* for this file see task include a file in language AArch64 assembly*/
.include "../includeConstantesARM64.inc"
 
/*********************************/
/* Initialized data              */
/*********************************/
.data
szMessResult:      .asciz "@ \n"                    // message result
szCarriageReturn:  .asciz "\n"
/*********************************/
/* UnInitialized data            */
/*********************************/
.bss 
qSum:                      .skip 8         // this program store sum and product in memory
qProd:                     .skip 8         // it is possible to use registers x22 and x28
sZoneConv:                 .skip 24
/*********************************/
/*  code section                 */
/*********************************/
.text
.global main 
main:                                       // entry of program
    ldr x0,qAdrqProd
    mov x1,1
    str x1,[x0]                             // init product
    ldr x0,qAdrqSum
    mov x1,0
    str x1,[x0]                             // init sum
 
    mov x25,5                               // x
    mov x24,-5                              // y
    mov x26,-2                              // z
    mov x21,1                               // one
    mov x23,3                               // three
    mov x27,7                               // seven
 
                                            // loop one
    mov x0,3
    mov x1,3
    bl computePow                           // compute 3 pow 3
    mov x20,x0                              // save result
    mvn x9,x23                              // x9 = - three
    add x9,x9,1
1: 
    mov x0,x9
    bl computeSumProd
    add x9,x9,x23                           // increment with three
    cmp x9,x20
    ble 1b
                                            // loop two
    mvn x9,x27                              // x9 = - seven
    add x9,x9,1
2: 
    mov x0,x9
    bl computeSumProd
    add x9,x9,x25                           // increment with x
    cmp x9,x27                              // compare to seven
    ble 2b
 
                                            // loop three
    mov x9,#550
    sub x20,x9,x24                          // x20 = 550 - y
    mov x9,#555
3: 
    mov x0,x9
    bl computeSumProd
    add x9,x9,#1
    cmp x9,x20
    ble 3b
                                            // loop four
    mov x9,#22
4: 
    mov x0,x9
    bl computeSumProd
    sub x9,x9,x23                           // decrement with three
    cmp x9,#-28
    bge 4b
                                            // loop five
    mov x9,1927
    mov x20,1939
5: 
    mov x0,x9
    bl computeSumProd
    add x9,x9,1
    cmp x9,x20
    ble 5b
                                            // loop six
    mov x9,x25                              // x9 = x
    mvn x20,x26                             // x20 = - z
    add x20,x20,1
6: 
    mov x0,x9
    bl computeSumProd
    sub x9,x9,x20
    cmp x9,x24
    bge 6b
                                            // loop seven
    mov x0,x25
    mov x1,11
    bl computePow                           // compute 11 pow x
    add x20,x0,x21                          // + one
    mov x9,x0
7: 
    mov x0,x9
    bl computeSumProd
    add x9,x9,1
    cmp x9,x20
    ble 7b
                                            // display result
    ldr x0,qAdrqSum
    ldr x0,[x0]
    ldr x1,qAdrsZoneConv                    // signed conversion value
    bl conversion10S                        // decimal conversion
    ldr x0,qAdrszMessResult
    ldr x1,qAdrsZoneConv
    bl strInsertAtCharInc                   // insert result at @ character
    bl affichageMess                        // display message
    ldr x0,qAdrszCarriageReturn
    bl affichageMess                        // display return line
    ldr x0,qAdrqProd
    ldr x0,[x0]
    ldr x1,qAdrsZoneConv                    // conversion value
    bl conversion10S                        // signed decimal conversion
    ldr x0,qAdrszMessResult
    ldr x1,qAdrsZoneConv
    bl strInsertAtCharInc                   // insert result at  @ character
    bl affichageMess                        // display message
    ldr x0,qAdrszCarriageReturn
    bl affichageMess                        // display return line
 
 
100:                                        // standard end of the program 
    mov x0,0                                // return code
    mov x8,EXIT                             // request to exit program
    svc 0                                   // perform the system call
 
qAdrsZoneConv:            .quad sZoneConv
qAdrszMessResult:         .quad szMessResult
qAdrszCarriageReturn:     .quad szCarriageReturn
/******************************************************************/
/*     compute the sum and prod                         */ 
/******************************************************************/
/* x0 contains the number  */
computeSumProd:
    stp x1,lr,[sp,-16]!          // save  registers
    asr x10,x0,#63
    eor x12,x10,x0
    sub x12,x12,x10             // compute absolue value
    ldr x13,qAdrqSum            // load sum
    ldr x11,[x13]
    add x11,x11,x12             // add sum
    str x11,[x13]               // store sum
    cmp x0,#0                   // j = 0 ?
    beq 100f                    // yes
    ldr x13,qAdrqProd
    ldr x11,[x13]
    asr x12,x11,#63             // compute absolute value of prod
    eor x14,x11,x12
    sub x12,x14,x12
    ldr x10,qVal2P27
    cmp x12,x10                 // compare 2 puissance 27
    bgt 100f
    mul x11,x0,x11
    str x11,[x13]               // store prod
100:
    ldp x1,lr,[sp],16           // restaur  2 registers
    ret                         // return to address lr x230
qAdrqSum:                .quad qSum
qAdrqProd:               .quad qProd
qVal2P27:                .quad 1<<27
/******************************************************************/
/*     compute pow                         */ 
/******************************************************************/
/* x0 contains pow  */
/* x1 contains number */
computePow:
    stp x1,lr,[sp,-16]!          // save  registers
    mov x12,x0
    mov x0,#1
1:
    cmp x12,#0
    ble 100f
    mul x0,x1,x0
    sub x12,x12,#1
    b 1b
100:
    ldp x1,lr,[sp],16           // restaur  2 registers
    ret                         // return to address lr x230
/********************************************************/
/*        File Include fonctions                        */
/********************************************************/
/* for this file see task include a file in language AArch64 assembly */
.include "../includeARM64.inc"
 