繁体   English   中英

如何修复nasm装配中斐波那契序列的溢出?

[英]How to fix overflow for fibonacci sequence in nasm assembly?

我是一名组装业余爱好者,我的任务之一是根据用户输入进行斐波那契数列。 因此,如果我的用户输入为5,则输出将像这样0 1 1 2 3将其放置在数组中,然后索引增加,并进行了一些算术运算以获得该序列。 用户输入限制为25,因此,如果用户输入为25,则我的输出应如上所示,一直到46368的值。首先,我使用al,bl和cl进行算术运算,但是意识到8位寄存器太小,我改为16位。

在某个时候,数字显示为负数,我确实知道这是由于符号位而造成的,而数字是带符号的数字,我如何使所有内容都未签名? 在某种程度上,我已经尝试过执行PRINT_UDEC,但是在某个时间点,该数字又回到了一个很小的数字,并且不会一直累加,实际上我在编写另一个程序时遇到了同样的事情,并且我使用了,这是8位的寄存器,所以我只是将其更改为16位的寄存器,但它确实起作用了,我也尝试将其更改为32位的寄存器,但仍然不起作用! 据我所知(纠正我,如果我错了),斧头的最大价值可以达到65536? 斐波那契数列的第25个数字是46368,仍在16位寄存器的范围内。 我该如何解决此问题?

%include "io.inc"

section .bss
fibo    resb 26 * 4; reserve an array of 25 uninitialized bytes
userInput   resb 4 ; reserve 4 bytes for userInput

section .text
global _main
_main:
    mov ebp, esp ; entry point for correct debugging
    xor edx, edx ; initializing my secondary index to 0
    mov eax, 0 ; a = 0
    mov ebx, 1 ; b = 1
    mov ecx, 0 ; c = 0

    PRINT_STRING "Enter a number between 3 and 25 inclusively:" ;prompt user for integer input
    NEWLINE
    GET_DEC 4, userInput ; 

    mov edi, userInput ; 
    mov esi, fibo ; 
    call indexInc ; 
    mov edx, 0 ; 
    call printarray ; 

indexInc:
    mov [esi], eax ; moves the a = 0 in the first element of the array
    inc esi ; increases array index
    mov [esi], ebx ; moves the b = 1 in the second element of the array
    inc esi ; increases array index
    mov edx, 3 ; secondary pointer for comparison purposes

forloop:
    cmp edx, [userInput] ; 
    jg term ;
    add ecx, eax ; 
    add ecx, ebx ; 
    mov [esi], ecx ; 
    mov eax, ebx ; 
    mov ebx, ecx ; 
    xor ecx, ecx ; 
    inc esi ; increase array index
    inc edx ; increase secondary pointer
    jmp forloop ; 

printarray:
    cmp edx, [userInput] ; 
    je term ; 
    PRINT_DEC 1, [fibo + edx] ; 
    NEWLINE
    inc esi ; increase array index
    inc edx ; increase pointer
    jmp printarray ; 

term:
    ret ; terminate program

尝试使用PRINT_DEC 4, [fibo + edx] PRINT_UDEC 4, [fibo + edx] PRINT_DEC 4, [fibo + edx]PRINT_UDEC 4, [fibo + edx]
这个来源来看。


请注意,装配线不必以;结尾; -这是评论的开始。
另外,您的程序流程和编码风格也很凌乱:除非您打高尔夫球或利用一些技巧,否则不要跨函数共享ret
向前跳比向后跳更难-如果可能,更喜欢do {} while (); while () {}
给标签赋予有意义的名称,并在需要时采用使功能标签脱颖而出的命名约定。
您的评论是有根据的。

我发现,如果将汇编代码(通常为代码)在空间上按逻辑块进行分组,则更容易遵循它-避免了文本墙的影响。
您将以两种不同的方式对寄存器进行清零 -充其量是很奇怪的(最坏的情况是可疑的)。

我认为您只需两个指令即可执行斐波那契步骤:

xchg eax, ebx
add ebx, eax

如果eaxf(n-1)ebxf(n)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM