几天前,我开始学习汇编语言,我正在尝试制作一个程序,以打印最多5个字符的 fibonacci系列,但是我的代码可以打印出奇怪的字符< / p>
我以为是因为ASCII转换系统,但是即使我将数值48加到数字上,它仍然是不正确的。
.model small
.data
lastFib DB 0
.code
main PROC
mov cx,5
mov dl,48
loopy:
add dl,lastFib
mov ah,2h
int 21h
mov lastFib,dl
loop loopy
ENDP
end main
答案 0 :(得分:1)
但是我的代码打印出了奇怪的字符
仅需添加48即可将(小)数字输出为字符。您一定不能允许这个增加的48篡改斐波那契数的计算。在下面的代码中,我在调用DOS之前以及刚将其取回之后立即添加48。
当前,您的代码根本不计算任何斐波那契数。基本方案是:
xchg dl, lastFib ; Exchange current with previous
add dl, lastFib ; Add previous to current
有6个位数的斐波那契数字:1、1、2、3、5、8。
通过输出之前计算下一个斐波那契数字,下面的代码设法在一个循环中打印所有6个数字。已计算出第七个数字(13),但从未显示。
.model small
.data
lastFib DB 0 ;previous
.code
main PROC
mov cx, 6
mov dl, 1 ;current
loopy:
add dl, 48 ;make character
mov ah, 02h
int 21h
sub dl, 48 ;take back
xchg dl, lastFib
add dl, lastFib
loop loopy
ENDP
end main
作为替代方案,它表明可以避免使用慢速loop
指令:
.model small
.data
lastFib DB 0 ;previous
.code
main PROC
mov dl, 1 ;current
loopy:
add dl, 48 ;make character
mov ah, 02h
int 21h
sub dl, 48 ;take back
xchg dl, lastFib
add dl, lastFib
cmp dl, 10
jb loopy
ENDP
end main
这次,循环仅持续DL
中的数字保持一位数字。
答案 1 :(得分:0)
我没有您的汇编程序(MASM?),但是代码相当简单,应该可以使用。
以C
和其他语言打印数字的一种简单方法是使用递归函数。但是组装起来很困难。在这里,我先计算位数,然后一一打印出来。由于AX
最多可保留5位数字,因此无循环操作非常简单,而且实际上更好。
.model small
.data
.code
main PROC
mov di, 0 ; Fibonacci(n-1); n = 1
mov si, 1 ; Fibonacci(n); n = 1
loopA: mov ax, si ; prepare for counting digits
xor cx, cx ; cx will be number of digits
mov bx, 10 ; print as decimal
loopDigit: xor dx, dx ; dx:ax is the dividend
div bx
inc cx
or ax, ax ; test if the quotient is 0
jnz loopDigit
; cx should be the number of digit
mov bp, si ; the number to be printed
cmp cx, 5 ; test if there are 5 digits
jb digit4
mov ax, bp ; get the number
mov bx, 10000
div bx
mov bp, dx ; the next number to be printed
mov dl, al ; the quotient, current digit
add dl, 48 ; convert to ASCII
mov ah, 2h
int 21h
digit4: cmp cx, 4 ; test if there are 4 or more digits
jb digit3
mov ax, bp ; get the number
mov bx, 1000
div bx
mov bp, dx ; the next number to be printed
mov dl, al ; the quotient, current digit
add dl, 48 ; convert to ASCII
mov ah, 2h
int 21h
digit3: cmp cx, 3 ; test if there are 4 or more digits
jb digit2
mov ax, bp ; get the number
mov bx, 100
div bx
mov bp, dx ; the next number to be printed
mov dl, al ; the quotient, current digit
add dl, 48 ; convert to ASCII
mov ah, 2h
int 21h
digit2: cmp cx, 2 ; test if there are 4 or more digits
jb digit1
mov ax, bp ; get the number
mov bx, 10
div bx
mov bp, dx ; the next number to be printed
mov dl, al ; the quotient, current digit
add dl, 48 ; convert to ASCII
mov ah, 2h
int 21h
digit1: mov dx, bp ; always need to print the last digit
add dl, 48 ; convert to ASCII
mov ah, 2h
int 21h
add di, si ; Fibonacci(n) = Fibonacci(n-1) + Fibonacci(n-2)
jc done ; overflow, done!
xchg di, si ; to keep them in order; si = F(n); di = F(n-1)
jmp loopA
done:
ENDP
end main
使用循环打印会更加复杂,因为我们需要在使用除数(并在每个循环中进行调整)之前计算除数(下面的cx
)
.model small
.data
.code
main PROC
mov di, 0 ; Fibonacci(n-1); n = 1
mov si, 1 ; Fibonacci(n); n = 1
mov cx, 1 ; 10^n_digits
loopA: mov ax, si ; prepare for counting digits
mov bx, 10 ; print as decimal
loopDigit: xchg ax, cx ; calculate 10^n_digits
mul bx
xchg cx, ax
xor dx, dx ; can be omitted, dx should be 0
div bx
or ax, ax ; test if the quotient is 0
jnz loopDigit
mov bx, si
mov bp, 10
loopPrint: mov ax, cx ; need to divide cx by 10 first
xor dx, dx
div bp
mov cx, ax
mov ax, bx ; get the number
xor dx, dx
div cx
mov bx, dx ; the next number to be printed
mov dl, al ; the quotient, current digit
add dl, 48 ; convert to ASCII
mov ah, 2h
int 21h
cmp cx, 1 ; should end?
jnz loopPrint
add di, si ; Fibonacci(n) = Fibonacci(n-1) + Fibonacci(n-2)
jc done ; overflow, done!
xchg di, si ; to keep them in order; si = F(n); di = F(n-1)
jmp loopA
done:
ENDP
end main