在 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
我正在尝试编写一个程序来找到第 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