在 nasm x86_64 程序集中寻找第 n 个素数

Finding the nth prime in nasm x86_64 assembly

我正在尝试编写一个程序来找到第 n 个素数 - 在本例中是第 10001 个素数。

目前,程序将每个数字检测为质数,所以我的结果最终是 10002。

当在 GDB 中单步执行程序时,从素数数组中检索到的值不是预期的 - 即在确定 3 是素数后,下一次迭代 4,程序从数组。

密码是:

%include '../resources.asm'

SECTION .data

SECTION .text
global main
extern malloc, free, calloc
main:
    ; Allocate space for primes
    mov rsi, 8
    mov rdi, 10001
    call calloc
    ; Store address in r10
    mov r10, rax
    ; First prime is 2
    mov qword [r10], 2
    ; r11 is current number of primes found
    mov r11, 1
    ; r12 is current number being checked
    mov r12, 2
.outer:
    ; Move to next number
    inc r12
    ; Reset array index
    mov rcx, 0
.inner:
    ; Get number and divisor in rax and rbx respectively
    mov rax, r12
    mov qword rbx, [r10 + rcx] ;;;; Issue here, rbx is 770?
    ; Increment array index
    inc rcx
    ; Get modulus
    call umod
    ; If modulus is 0, number is not prime, move to next number
    cmp rax, 0
    jz .outer
    ; See if we've hit the end of current list of primes
    cmp rcx, r11
    jnz .inner
    ; If we are at the end of the list of primes, move the current number into the array
    mov qword [r10 + rcx], r12
    inc r11
    ; Stop if we've got the 10001st prime
    cmp r11, 10001
    jl .outer

以及资源中的 umod 片段

;
; int udiv(int rax, int rbx) -> rax, rbx
; Unsigned division
udiv:
    push rdx

    xor rdx, rdx
    div rbx
    mov rbx, rdx

    pop rdx
    ret

;
; int umod(int rax, int rbx) -> rax
; Unsigned modulus operation
umod:
    call udiv
    mov rax, rbx

    ret

请注意,我意识到我可能没有遵循正确的参数传递约定等。觉得对您有帮助,欢迎留言。

正如评论中所指出的,我没有将索引寄存器缩放 8 来补偿存储的 8 字节值。生成的固定代码在这里:

%include '../resources.asm'

SECTION .data

SECTION .text
global main
extern malloc, free, calloc
main:
    ; Allocate space for primes
    mov rsi, 8
    mov rdi, 10001
    call calloc
    ; Store address in r10
    mov r10, rax
    ; First prime is 2
    mov qword [r10], 2
    ; r11 is current number of primes found
    mov r11, 1
    ; r12 is current number being checked
    mov r12, 2
.outer:
    ; Move to next number
    inc r12
    ; Reset array index
    mov rcx, 0
.inner:
    ; Get number and divisor in rax and rbx respectively
    mov rax, r12
    mov r13, rcx
    imul r13, 8
    mov qword rbx, [r10 + r13]
    ; Increment array index
    inc rcx
    ; Get modulus
    call umod
    ; If modulus is 0, number is not prime, move to next number
    cmp rax, 0
    jz .outer
    ; See if we've hit the end of current list of primes
    cmp rcx, r11
    jnz .inner
    ; If we are at the end of the list of primes, move the current number into the array
    mov r13, rcx
    imul r13, 8
    mov qword [r10 + r13], r12
    inc r11
    ; Stop if we've got the 10001st prime
    cmp r11, 10001
    jb .outer

    ; Print out result
    mov rax, r12
    call itoa
    mov rdi, rax
    call sprintlf
    call free



    call exit