You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

nasm x86_64汇编查找第10001个素数时判定与数组取值异常如何解决

问题修复方案

核心错误原因

你遇到的读取素数数值异常的核心问题是数组地址偏移计算错误:

  • 你声明素数数组的每个元素是8字节的qword类型,但使用索引rcx计算内存地址时没有乘以8,导致始终访问错位的内存地址,读取到的自然是无效乱值(比如你遇到的770)。
  • 后续存储新素数的逻辑也存在同样的偏移计算错误。

修正后的代码调整点

1. 修复数组寻址逻辑

两处读写数组的代码都要将索引乘以8:

; 读取素数的代码从
mov qword rbx, [r10 + rcx]
; 改为
mov qword rbx, [r10 + rcx*8]

; 存储新素数的代码从
mov qword [r10 + rcx], r12
; 改为
mov qword [r10 + rcx*8], r12

2. 补充寄存器调用约定适配

根据x86_64 System V调用约定:

  • r10、r11属于调用者保存寄存器,调用calloc等libc函数后可能被修改,建议改用r12、r13、r14这类被调用者保存寄存器存储全局状态,或者在调用函数前手动入栈保存。
  • main函数使用被调用者保存寄存器前,需要在函数开头入栈备份,函数退出前出栈恢复,避免破坏上层调用者的状态,示例如下:
main:
    push r12
    push r13
    push r14
    ; 原有逻辑
    ; ...
    ; 函数退出前恢复
    pop r14
    pop r13
    pop r12
    ret

3. 可选性能优化

要查找第10001个素数,可以增加两个优化点大幅提升运行速度:

  • 因为2是唯一的偶素数,后续待校验数可以直接从3开始,每次加2跳过所有偶数,减少一半校验次数
  • 校验素数时不需要遍历所有已存储的素数,只需要遍历到小于等于当前待校验数平方根的素数即可,不需要校验更大的素数

修正后可正常运行的完整代码片段

%include '../resources.asm'

SECTION .text
global main
extern calloc
main:
    push r12
    push r13
    push r14
    push r15
    ; 为素数数组分配空间
    mov rsi, 8
    mov rdi, 10001
    call calloc
    ; 将数组地址存入r12
    mov r12, rax
    ; 第一个素数是2
    mov qword [r12], 2
    ; r13存储当前已找到的素数数量
    mov r13, 1
    ; r14存储当前待校验的数字,从3开始跳过偶数
    mov r14, 3
.outer:
    ; 重置数组索引
    mov rcx, 0
.inner:
    ; 将待校验数字存入rax,除数存入rbx
    mov rax, r14
    mov qword rbx, [r12 + rcx*8]
    ; 数组索引自增
    inc rcx
    ; 计算模值
    call umod
    ; 若模值为0,说明当前数不是素数,跳转校验下一个数字
    cmp rax, 0
    jz .next_num
    ; 校验是否已经遍历完当前已存储的所有素数
    cmp rcx, r13
    jnz .inner
    ; 若已遍历完所有已存储素数,说明当前数为素数,存入数组
    mov qword [r12 + rcx*8], r14
    inc r13
    ; 已找到第10001个素数则停止运行
    cmp r13, 10001
    je .exit
.next_num:
    ; 跳过偶数,每次加2
    add r14, 2
    jmp .outer
.exit:
    ; 第10001个素数存在r14中,可自行添加输出逻辑
    pop r15
    pop r14
    pop r13
    pop r12
    ret

内容的提问来源于stack exchange,提问作者H. Ross

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 00:54:02