-3

I'm trying to write in in-line assembly language whether the iteration from 2 to 200 is prime, given we're doing i2+1 on each iteration. I have started writing it, but it just computes every second number from 2 - 200.

I know I have my logic messed up in the prime loop, as it obviously isn't correctly checking whether than number is prime, but do not have nearly enough experience with Assembly to understand what I am doing wrong.

Any help would be greatly appreciated. Here is my code for reference:

#include <stdio.h>

int main() {
    int i = 2, prime;
    int c = 2;

    __asm {
        top:    mov eax, i
                cmp eax, 200
                jg done
                mul i
                add eax, 1
        prime:  mov edx, 0
                div c
                cmp edx, 0
                je done
                mov prime, 1
                cmp prime, 1
                jne done
    }
    printf("%d\n", i);
    __asm {
                add i, 2
                loop top
        done:   nop
    }
}

The proper run of the program should compute : 2, 4, 6, 10, 14 ...

Clifford
  • 88,407
  • 13
  • 85
  • 165
axis100
  • 13
  • 4
  • Did you try using a debugger to trace through the logic of the code? – Karl Knechtel Dec 03 '21 at 21:40
  • When I write asm code, I usually put a sidebar comment on _each_ line. If I have C code that I'm implementing, I usually refer the the variables and statements. For example, see my answer: https://stackoverflow.com/questions/36538325/mips-linked-list/36560575#36560575 – Craig Estey Dec 03 '21 at 22:05
  • You can always code it up in C and check the `-O0` generated assembly as a good starting point. Kinda cheating to directly turn that in tho. – yano Dec 03 '21 at 22:21
  • 1
    @yano `-O0` is always bad starting point https://godbolt.org/z/bvMEPx63a – 0___________ Dec 03 '21 at 22:28
  • Analyze the code below. You have everything there – 0___________ Dec 03 '21 at 22:44
  • `mov prime, 1` followed by `cmp prime,1` doesn't seem useful. We surely know what prime is at that point. Also, the `loop` instruction expects a counter in the `ecx` register. Can't see where that is loaded. – BoP Dec 03 '21 at 23:21
  • It's probably not safe in MSVC to jump from one inline asm statement to another. It might happen to work, though, if you don't depend on any register values (like ECX) being preserved, since the code between statements is just a function call. – Peter Cordes Dec 04 '21 at 02:14
  • @0___________ ok I'll bite,, why is it that `-O0` is a bad starting point? It's even easier to follow on godbolt with the C line highlighting they offer when you hover over the corresponding assembly. – yano Dec 04 '21 at 05:31
  • Please go through with this logic. https://stackoverflow.com/questions/15743192/check-if-number-is-prime-number – Sandeep Jadhav Dec 09 '21 at 14:44

1 Answers1

0

Not the answer but your assembly looks a bit short for the task :)

.LC0:
        .string "%4u,"
main:
        push    rbx
        mov     ebx, 2
.L5:
        mov     esi, ebx
        mov     ecx, 2
        imul    esi, ebx
        inc     esi
.L3:
        mov     eax, esi
        xor     edx, edx
        div     ecx
        test    edx, edx
        je      .L2
        inc     ecx
        mov     eax, ecx
        imul    eax, ecx
        cmp     esi, eax
        jnb     .L3
        mov     esi, ebx
        mov     edi, OFFSET FLAT:.LC0
        xor     eax, eax
        call    printf
.L2:
        inc     ebx
        cmp     ebx, 200
        jne     .L5
        xor     eax, eax
        pop     rbx
        ret

It is of course compiler-generated code:

int __attribute__((always_inline)) isprime(unsigned x)
{
    int result = 1;
    for(unsigned y = 2; y * y <= x; y++)
    {
        if(!(x % y)) 
        {
            result = 0;
            break;
        }
    }
    return result;
}

int main(void)
{
    for(unsigned x = 2; x < 200 ; x++)
    {
        if(isprime(x * x + 1)) printf("%4u,", x) ;
    }
}

https://godbolt.org/z/Wjr8one9M

0___________
  • 60,014
  • 4
  • 34
  • 74
  • That's calling printf using the x86-64 System V ABI's calling convention, not Windows cdecl. But yes, possibly not useless since it did only use 32-bit legacy registers. – Peter Cordes Dec 04 '21 at 02:11