0

I am trying to convert this code over to arm assembly and am having some trouble with it.

        // Multiply with current digit of first number
        // and add result to previously stored result
        // at current position. 
        int sum = n1*n2 + result[i_n1 + i_n2] + carry;

        // Carry for next iteration
        carry = sum/10;

        // Store result
        result[i_n1 + i_n2] = sum % 10;

        i_n2++;
    }

so far this is what i have, my biggest issue is the portion where it is multiplying

    int sum = n1*n2+result[i_n1 + i_n2] + carry

i_n1 and i_n2 are just indexes used to find position in result n1 and n2 are numbers result is a pointer to memory. I am also having a smaller issue where the compiler is giving me errors because of how I am using MOD in ;result[i_n1 + i_n2] = sum % 10; can someone please let me know what i am doing wrong and how to correct this.

this is what i have so far

    ;int sum = n1*n2 + result[i_n1 + i_n2] + carry; 
ldr r0,=carry
ldr r1,=i_n1
str r1,[r1] ;stores value of r1 into r1
ldr r2,=i_n2
str r2,[r2] ; stores value of r2 in r2
ldr r3,=result
add r4,r1,r2 ; value of i_n1+ value of i_n2
ldr r5,=n2
ldr r6,=n1
mul r7, r5,r6



    ;carry = sum/10;
 mov r1,#10
 ldr r2,=sum
 sdiv r0,r2,r1 ;divide r2 by r0 sum/10
 ldr r3,=carry
 str r0,[r3]


    ;result[i_n1 + i_n2] = sum % 10;
ldr r0,=sum
***mov r1,r0,MOD 10 ;divides r0 by mod 10 and stores remainder in r1*****
ldr r2,i_n1
ldr r3,=i_n2
add r4,r2,r3 ;i_n1+i_n2
ldr r5,=result  
str r1,[r5] ;stores value of sum %10 into r5 which is result
;i_n2++; 
add r3,#1  
Shazee
  • 13
  • 5
  • There is no `MOD 10` operand modifier. Why do you think such a thing exists? – fuz Apr 28 '18 at 22:46
  • @LưuVĩnhPhúc: Not a duplicate: the OP wants a runtime operation, but is using the operator for an assemble-time operation rather than asm instructions. The only run-time operations you can do with an operand-modifier on ARM are shifts/rotates. – Peter Cordes Apr 29 '18 at 02:21
  • @PeterCordes I know, but there's a runtime solution in that question – phuclv Apr 29 '18 at 12:04

1 Answers1

1

as Fuz suggested there's no MOD command in Arm Assembly. Anyway you can create a mod function with subs. Actually I'm not very good in assembly but I made an example that seems working.

    .data
n1:     .word 10
n2:     .word 15
carry:  .word 5
vector: .word 1, 2, 3, 4, 5, 6, 7   
in1:    .word 2
in2:    .word 1

    .text
main:
;Load n1, n2, carry, in1, in2
    ldr r0, =n1
    ldr r0, [r0]
    ldr r1, =n2
    ldr r1, [r1]
    ldr r2, =carry
    ldr r2, [r2]
    ldr r3, =in1
    ldr r3, [r3]
    ldr r4, =in2
    ldr r4, [r4]
    ;Load vector
    ldr r5, =vector
    add r5, r5, r3, lsl #2  ;Add in1 << 2 (Each pos is a word)
    add r5, r5, r4, lsl #2 ;Add in2 << 2 
    ldr r6, [r5]

    ;int sum = n1*n2+result[_n1 + i_n2] + carry
    mul r7, r0, r1
    add r7, r7, r6
    add r7, r7, r2

    ;Passing argument in r0 (Saving r0 in r8)
    mov r8, r0
    mov r0, r7
    bl dividebyten
    mov r2, r0
    ;Restore sum in r0 to get mod
    mov r0, r7
    bl mod
    str r0, [r5]
    ;Restore n1 in r0
    mov r0, r8
    add r4, r4, #1


    swi 0x11


mod:
    stmfd sp!, {r1 - r9, lr}
    mov r1, #10
    mov r2, r0
iter:
    cmp r2, r1
    blt exit
    sub r2, r2, r1
    b iter

dividebyten:
    stmfd sp!, {r1 - r9, lr}
    mov r1, #10
    mov r2, #0
loop:
    cmp r0, r1
    blt exit
    add r2, r2, #1
    sub r0, r0, r1
    b loop

exit:
    mov r0, r2
    ldmfd sp!, {r1 - r9, pc}

    .end
  1. When you use ldr reg, =var you're loading the memory address of that variable. If you want to load the value you need to do another ldr with that reg. For example :

    ldr r0, =carry ldr r0, [r0] ;Load in r0 the value stored at the memory address in r0

  2. You're storing r1 in the memory address which r1 contains. For example if r1 = 0x12345 you're storing 0x12345 in the memory address 0x12345 (What?).

    str r1,[r1] ;stores value of r1 into r1

  3. Because of point 1 you're adding the addresses of in1 and in2

    add r4,r1,r2 ; value of i_n1+ value of i_n2

That's all I understood about your code..

Steph
  • 26
  • 4
  • `sdiv` is much faster than a subtract loop except for very small inputs where the loop only runs once or twice. You can use the `sdiv` result (which the OP already uses to get `sum/10`) to get the modulo result the way a compiler would, by multiplying again and subtracting. `x % 10 = x - 10*(x/10)` – Peter Cordes Apr 29 '18 at 02:18
  • `ldr r3, =in1` `ldr r3, [r3]` `ldr r4, =in2` `ldr r4, [r4]` what are these doing exactly? I thought these are suppose to tell me how far to the right to the right of the result? wont these just load in values stored at the address? Also my program is multiplying integers, where as yours is multiplying words. – Shazee Apr 29 '18 at 02:55
  • Thanks @PeterCordes , I didn't know the existence of sdiv. – Steph Apr 29 '18 at 06:33
  • @Shazee ldr r3, =in1 load the address of the location where in1 is stored. Than with another ldr r3, [r3] you're loading in r3 the value of the memory address where r3 is pointing. – Steph Apr 29 '18 at 06:39
  • @Shazee: Read Steph's answer, and run your code in a debugger. Look at the values in registers and memory after your instructions run, and notice that they are *not* what you want. `str` stores the register value to memory, but it will be holding a pointer value at that point. (And there would be no point storing anything to `n1` at the start of your program; if you were going to do that you should have just put a different static value in `n1` to start with! Or better, not used static storage at all and just used registers to keep the values you need.) – Peter Cordes Apr 29 '18 at 06:40
  • okay so I should not be using str, I should be using LDR instead the way Steph has used it. I am not very good at using assembly and i am using keil debugger. What should happn when to my registers when I ldr in1 and in2? I tested steph's code as well and modified to fit mine but it is saying the memory in those locations are empty, is that what is suppose to happen? – Shazee Apr 29 '18 at 14:15
  • when i search memory after the ` mul r7, r0, r1` command i do not see any math actually happening. My program is taking in an int value of 15 and 16 which is stored at` r0` and `r1` am i suppose to be seeing any kind of multiplication occur at this point? – Shazee Apr 29 '18 at 14:56
  • when you say "it is saying the memory in those locations are empty" what do you mean? Does it loads 0? Have you declared them in the data section? – Steph Apr 29 '18 at 15:14
  • After the mul command you should see in r7 the result of the operation r0 * r1. Maybe this site can help you : www.keil.com/support/man/docs/armasm/armasm_dom1361289882394.htm – Steph Apr 29 '18 at 15:19