所以我正在尝试使用给我的伪代码创建一个模拟The Collatz Sequence的程序,每行打印5个数字。我设法将代码写入x86汇编代码,但是当我编译并运行时,我没有得到所需的结果。相反,我被要求输入(这是正确的),我得到252 521的无限循环。我无法弄清楚为什么我认为这可能是我将n
(整数)传递给每个过程的方式;但是,我之前从未做过这样的编码,因为我对汇编很新。我在64位win8上使用TASM(如果有帮助)。
我有两个链接在一起的.asm文件,Ulamtst和Ulam,Ulam进行计算并显示结果,而Ulamtst从用户获取n的值并将其发送给Ulam。 getint和putint是asm文件,允许更容易输入/输出整数,并且不是问题(因为我没有编码它们,它们来自我的教授)。
此外,我认为也许我如何开始计算cx,我觉得我可能在Ulam.asm中做错了,但是,就像我说的,我不确定。
Ulamtst:
title UlamTst.asm ; Calculates The Collatz sequence a_(n+1) = a_n div 2, if a_n mod 2 = 0 = 3*a_n + 1, otherwise
.model small
.stack 100h
.data
include const.inc
n dw ?
nl db cr, lf, '$'
getN db 'n? $'
.code
extrn getint: proc, ulam: proc
main proc
; initialize DS
mov ax, @data
mov ds, ax
loop01:
; write 'n? ';
mov ah, dispstr
mov dx, offset getN
int dosfunc
; read n;
call getint
mov n, ax
; exit when n <= 0
cmp n, 0
jle endloop01
; ulam( n)
mov ax, n
call ulam
mov n, ax
; write cr, lf
mov dx, offset nl
mov ah, wrstr
int dosfunc
jmp loop01
endloop01:
; return -- to DOS
mov ah, ret2dos
int dosfunc
main endp
end main
乌拉姆:
title ulam.asm ; Calculates The Collatz sequence a_(n+1) = a_n div 2, if a_n mod 2 = 0 = 3*a_n + 1, otherwise
.model small
.stack 100h
.data
include const.inc
n dw ?
nl db cr, lf, '$'
showCount db cr, lf, 'Length: $'
.code
extrn putint: proc
public ulam
ulam proc ;(n)
; a_(n+1) = a_n div 2, if a_n mod 2 = 0 = 3*a_n + 1, otherwise
; input: AX = n
; output: none
; save regs
push ax ; ax = n
push cx ; assigned to count
; write cr, lf, n;
mov dx, offset nl
mov ah, wrstr
int dosfunc
call putint
; count := 0
xor cx, cx
repeat01:
;if02 count mod 5 = 0
mov n, ax
mov ax, 5
idiv cx
cmp dx, 0
jne endif02
; then02
; write cr, lf
mov dx, offset nl
mov ah, wrstr
int dosfunc
endif02:
; count := count + 1;
inc cx
; if03 n mod 2 = 0
mov ax, 2
idiv n
cmp dx, 0
jne else03
; then
; n := n div 2
mov ax, n
mov bx, 2
idiv bx
mov n, ax
jmp endif03
else03:
; n := n*3 + 1
mov ax, 3
imul n
add ax, 1
mov n, ax
endif03:
; write ' ', n
mov dl, ' '
mov ah, wrchr
int dosfunc
mov ax, n
call putint
; until n = 1;
cmp n, 1
jne repeat01
; endrepeat01
; write cr, lf, 'Length: ', count;
mov ah, dispstr
mov dx, offset showCount
int dosfunc
mov ax, cx
call putint
mov ax, n
; restore registers
pop cx
pop ax
; return
ret
; return -- to DOS
mov ah, ret2dos
int dosfunc
ulam endp
end ulam
这是我在为n输入1时得到的结果,稍微修改我的代码后,现在我得到以下结果,_
持续闪烁