【发布时间】:2017-09-09 09:08:54
【问题描述】:
我正在尝试使用 NASM 汇编器在汇编中实现斐波那契算法。 这是算法的伪代码
fibonacci_it(n):
int f_i-1 = 1;
int f_i-2 = 1;
if (n==0):
return 1;
else:
int i = 1;
int f_i = 1;
while (i < n):
f_i = f_i-1 + f_i-2
f_i-2 = f_i-1
f_i-1 = f_i
i = i + 1
return f_i
我尝试过的看起来是这样的:
%include "asm_io.inc"
segment .data
prompt db "Enter number: ", 0
segment .bss
fibnum resd 1
segment .text
global asm_main
asm_main:
enter 0,0
pusha
mov eax, prompt
call print_string
call read_int
mov [fibnum], eax
push dword [fibnum]
call fib_it
call print_int
popa
mov eax, 0
leave
ret
fib_it:
enter 12,0 ; 3 local variables: f_i, f_i-1, f_i-2
pusha
mov dword [ebp-4], 1 ; initialize f_i
mov dword [ebp-8], 1 ; initialize f_i-1
mov dword [ebp-12], 1 ; initialize f_i-2
mov ecx, 1 ; i = 1
mov edx, 1 ; comparison operator for n
cmp [ebp+8], edx ; n <= 1 ?
jbe end_fib_it ; if n <= 1 -> end and return 1
fib_it_while:
dump_regs 1
mov eax, [ebp-8] ; eax = f_i-1
add eax, [ebp-12] ; eax = f_i-1 + f_i-2
mov [ebp-4], eax ; f_i = f_i-1 + f_i-2
mov eax, [ebp-8] ; eax = f_i-1
mov [ebp-12], eax ; f_i-2 = f_i-1
mov eax, [ebp-4] ; eax = f_i
mov [ebp-8], eax ; f_i-1 = f_i
inc ecx ; i += 1
cmp ecx, [ebp+8] ; i < n ?
jae end_fib_it ; end while loop if i < n
jmp fib_it_while ; else -> loop again
end_fib_it:
mov eax, [ebp-4] ; return f_i
popa
leave
ret
程序首先从终端读取一个整数。然后它将它作为 fib_it 的参数推送到堆栈
当我运行程序时,它会出现分段错误。我发现每次jbe end_fib_it 或jae end_fib_it 为真并且程序必须跳转然后它给出分段错误。我用dump_regs 进行了更多调试,发现while 循环运行完美,jmp fib_it_while 没有问题。
【问题讨论】:
-
将所有数据保存在内存中而不是寄存器中非常慢。
add eax,edx/add edx,eax计算斐波那契数列的效率更高!请参阅stackoverflow.com/questions/32659715/… 了解一些编写它的好方法,从相当简单的开始。