-1

I am a university student learning how to write assembly code for the ARM platform (ARM v1.2).
First, I wrote this program in C:

#include <stdio.h>
#include <math.h>

int main()
{
    int M, N;
    int count = 0;
    scanf("%d %d", &M, &N);
    for(int k = M; k<N+1; k++){
        int T = sqrt(k);
        for(int i = 2; i<T+1; i++){
            if(k % i == 0){
                break;
            }
            if(i == T){
                count++;
                break;
            }
        }
    }
    printf("%d", count);
    return 0;
}

Now I want to convert it into ARM assembly language (ARM v1.2).
I already wrote the scanf and printf part as follows:

            AREA text, CODE
    
        

EXPORT print
            EXPORT scan
            EXPORT print_char

print
            ;Entry: Takes char in r0
            ;Conforms to APCS
            ;Call SYS_WRITEC, with r1 containing a POINTER TO a character
        
            ;SYS_WRITEC = 3, SYS_WRITE0 = 4, SYS_READC = 7
        
            stmfd   sp!, {r4-r12, lr}
            mov     r1, r0
            mov     r0, #4
            swi     0x123456
            ldmfd   sp!, {r4-r12, pc}

scan
            stmfd   sp!, {lr}
            mov     r0, #7
            swi     0x123456
            ldmfd   sp!, {pc}

print_char
            stmfd   sp!, {r0, lr}
                                ; push the register that
                                ; you want to save
            adr     r1, char
            strb    r0, [r1]
            mov     r0, #3
            swi     0x123456
            
            ldmfd   sp!, {r0,pc}

char        DCB     0   

How can I proceed to convert the rest of the code?
I appreciate any feedback, even rough ideas.

Thank you for reading my question.

Addendum:
ARM v1.2 refers to

ARM®, Developer Suite, Version 1.2, Assembler Guide, Copyright © 2000, 2001 ARM Limited.

Sep Roland
  • 33,889
  • 7
  • 43
  • 76
이건웅
  • 39
  • 2
  • What part of the translation are you stuck at. I'm not aware of any “arm v1.2.” Can you explain what you mean by that? – fuz May 07 '22 at 18:25
  • 1
    Can you narrow the question down, so it doesn't sound like "please complete the assignment for me"? Do you know how to write loops in assembly? Do you know how to compute a modulo? What do you want to do about the square root (which as written requires a call to the standard library, as well as converting from floating point)? – Nate Eldredge May 07 '22 at 18:44
  • 1
    By what you're showing, you haven't even started working on the `main` with the prime algorithm that you're showing as the C code. You need to show your effort and ask a specific question about where you're stuck. Otherwise we don't know what you need to know so you can do this. – Erik Eidt May 07 '22 at 19:18
  • I can't see the relationship between the assembly code `print`, `scan`, and `print_char` as the `main` doesn't need those -- it uses `scanf` and `printf` and `sqrt` instead. – Erik Eidt May 07 '22 at 19:19
  • 1
    Just `objdump -d` the .o file and you have a good starting point. – Goswin von Brederlow May 07 '22 at 19:38

1 Answers1

1

As mentioned in the comments, a starting point is the assembly code generated by your C compiler.

In order to demonstrate the output of the C code as ARM assembly (although Apple M1 as target platform, arm64):

$ gcc -c -g prime.c   
$ objdump --source -d prime.o                 

prime.o:        file format mach-o arm64


Disassembly of section __TEXT,__text:

0000000000000000 <ltmp0>:
; {
       0: ff 43 01 d1   sub     sp, sp, #80
       4: fd 7b 04 a9   stp     x29, x30, [sp, #64]
       8: fd 03 01 91   add     x29, sp, #64
       c: bf c3 1f b8   stur    wzr, [x29, #-4]
;     int count = 0;
      10: bf 03 1f b8   stur    wzr, [x29, #-16]
      14: 00 00 00 90   adrp    x0, #0
      18: 00 00 00 91   add     x0, x0, #0
;     scanf("%d %d", &M, &N);
      1c: e8 03 00 91   mov     x8, sp
      20: a9 23 00 d1   sub     x9, x29, #8
      24: 09 01 00 f9   str     x9, [x8]
      28: a9 33 00 d1   sub     x9, x29, #12
      2c: 09 05 00 f9   str     x9, [x8, #8]
      30: 00 00 00 94   bl      0x30 <ltmp0+0x30>
;     for(int k = M; k<N+1; k++){
      34: aa 83 5f b8   ldur    w10, [x29, #-8]
      38: aa c3 1e b8   stur    w10, [x29, #-20]
      3c: a8 c3 5e b8   ldur    w8, [x29, #-20]
      40: a9 43 5f b8   ldur    w9, [x29, #-12]
      44: 29 05 00 11   add     w9, w9, #1
      48: 08 01 09 6b   subs    w8, w8, w9
      4c: ca 04 00 54   b.ge    0xe4 <ltmp0+0xe4>
;         int T = sqrt(k);
      50: a0 c3 5e bc   ldur    s0, [x29, #-20]
      54: 01 1c a0 4e   mov.16b v1, v0
      58: 22 a4 20 0f   sshll.2d        v2, v1, #0
      5c: 41 d8 61 5e   scvtf   d1, d2
      60: 21 c0 61 1e   fsqrt   d1, d1
      64: 28 00 78 1e   fcvtzs  w8, d1
      68: a8 83 1e b8   stur    w8, [x29, #-24]
      6c: 48 00 80 52   mov     w8, #2
;         for(int i = 2; i<T+1; i++){
      70: a8 43 1e b8   stur    w8, [x29, #-28]
      74: a8 43 5e b8   ldur    w8, [x29, #-28]
      78: a9 83 5e b8   ldur    w9, [x29, #-24]
      7c: 29 05 00 11   add     w9, w9, #1
      80: 08 01 09 6b   subs    w8, w8, w9
      84: 8a 02 00 54   b.ge    0xd4 <ltmp0+0xd4>
;             if(k % i == 0){
      88: a8 c3 5e b8   ldur    w8, [x29, #-20]
      8c: a9 43 5e b8   ldur    w9, [x29, #-28]
      90: 0a 0d c9 1a   sdiv    w10, w8, w9
      94: 49 7d 09 1b   mul     w9, w10, w9
      98: 08 01 09 6b   subs    w8, w8, w9
      9c: 48 00 00 35   cbnz    w8, 0xa4 <ltmp0+0xa4>
;                 break;
      a0: 0d 00 00 14   b       0xd4 <ltmp0+0xd4>
;             if(i == T){
      a4: a8 43 5e b8   ldur    w8, [x29, #-28]
      a8: a9 83 5e b8   ldur    w9, [x29, #-24]
      ac: 08 01 09 6b   subs    w8, w8, w9
      b0: a1 00 00 54   b.ne    0xc4 <ltmp0+0xc4>
;                 count++;
      b4: a8 03 5f b8   ldur    w8, [x29, #-16]
      b8: 08 05 00 11   add     w8, w8, #1
      bc: a8 03 1f b8   stur    w8, [x29, #-16]
;                 break;
      c0: 05 00 00 14   b       0xd4 <ltmp0+0xd4>
;         for(int i = 2; i<T+1; i++){
      c4: a8 43 5e b8   ldur    w8, [x29, #-28]
      c8: 08 05 00 11   add     w8, w8, #1
      cc: a8 43 1e b8   stur    w8, [x29, #-28]
      d0: e9 ff ff 17   b       0x74 <ltmp0+0x74>
;     for(int k = M; k<N+1; k++){
      d4: a8 c3 5e b8   ldur    w8, [x29, #-20]
      d8: 08 05 00 11   add     w8, w8, #1
      dc: a8 c3 1e b8   stur    w8, [x29, #-20]
      e0: d7 ff ff 17   b       0x3c <ltmp0+0x3c>
;     printf("%d", count);
      e4: a8 03 5f b8   ldur    w8, [x29, #-16]
      e8: e0 03 08 aa   mov     x0, x8
      ec: 09 00 00 90   adrp    x9, #0
      f0: 29 01 00 91   add     x9, x9, #0
      f4: e0 0f 00 f9   str     x0, [sp, #24]
;     printf("%d", count);
      f8: e0 03 09 aa   mov     x0, x9
      fc: e9 03 00 91   mov     x9, sp
     100: ea 0f 40 f9   ldr     x10, [sp, #24]
     104: 2a 01 00 f9   str     x10, [x9]
     108: 00 00 00 94   bl      0x108 <ltmp0+0x108>
     10c: 08 00 80 52   mov     w8, #0
;     return 0;
     110: e0 03 08 aa   mov     x0, x8
     114: fd 7b 44 a9   ldp     x29, x30, [sp, #64]
     118: ff 43 01 91   add     sp, sp, #80
     11c: c0 03 5f d6   ret
Franck
  • 1,340
  • 2
  • 3
  • 15
  • 1
    Uncommented debug-mode asm is pretty clunky, so many stores / reloads. [How to remove "noise" from GCC/clang assembly output?](https://stackoverflow.com/q/38552116). – Peter Cordes May 08 '22 at 07:12