查找 i*i+1 是不是为素数,汇编语言

Posted

技术标签:

【中文标题】查找 i*i+1 是不是为素数,汇编语言【英文标题】:Find if i*i+1 is prime, Assembly Language查找 i*i+1 是否为素数,汇编语言 【发布时间】:2022-01-10 05:02:52 【问题描述】:

我正在尝试用内联汇编语言编写从 2 到 200 的迭代是否是素数,因为我们在每次迭代中都在执行 i2+1。我已经开始写了,但它只计算 2 到 200 之间的每秒数。

我知道我的逻辑在素数循环中搞砸了,因为它显然没有正确检查数字是否为素数,但没有足够的组装经验来理解我做错了什么。

任何帮助将不胜感激。这是我的参考代码:

#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
    

程序的正确运行应该计算:2、4、6、10、14 ...

【问题讨论】:

您是否尝试过使用调试器来跟踪代码的逻辑? 当我写 asm 代码时,我通常会在 each 行加上侧边栏注释。如果我有要实现的 C 代码,我通常会引用变量和语句。比如看我的回答:***.com/questions/36538325/mips-linked-list/… 您始终可以用 C 对其进行编码并检查 -O0 生成的程序集作为一个很好的起点。有点作弊直接把它转过来。 @yano -O0 总是不好的起点godbolt.org/z/bvMEPx63a 分析下面的代码。你拥有一切 【参考方案1】:

不是答案,但你的程序集看起来有点短 :)

.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

当然是编译器生成的代码:

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

【讨论】:

这是使用 x86-64 System V ABI 的调用约定调用 printf,而不是 Windows cdecl。但是,是的,可能不是没用的,因为它只使用了 32 位传统寄存器。

以上是关于查找 i*i+1 是不是为素数,汇编语言的主要内容,如果未能解决你的问题,请参考以下文章

编写一个C语言程序判断一个数是不是是素数

c语言求1-1000素数的算法问题

求C语言中 判断素数的 代码!!!!!

c语言判断一个数是不是为质数

如何用c语言编程判断一个数是否素数?

C++判断素数的代码