Assembly 无限循环x86程序集
因此,我试图创建一个程序,使用提供给我的伪代码模拟Collatz序列,每行打印5个数字。我设法将代码写入x86汇编代码,但是当我编译并运行时,我没有得到想要的结果。相反,我被要求输入(这是正确的),我得到一个252521的无限循环。我不明白为什么我认为这可能是我将Assembly 无限循环x86程序集,assembly,x86,Assembly,X86,因此,我试图创建一个程序,使用提供给我的伪代码模拟Collatz序列,每行打印5个数字。我设法将代码写入x86汇编代码,但是当我编译并运行时,我没有得到想要的结果。相反,我被要求输入(这是正确的),我得到一个252521的无限循环。我不明白为什么我认为这可能是我将n(整数)传递给每个进程的方式;然而,我以前从未做过这样的编码,因为我对汇编相当陌生。我在64位win8上使用TASM(如果有帮助的话) 我有2个链接在一起的.asm文件,Ulammtst和Ulam,Ulam进行计算并显示结果,而Ula
n
(整数)传递给每个进程的方式;然而,我以前从未做过这样的编码,因为我对汇编相当陌生。我在64位win8上使用TASM(如果有帮助的话)
我有2个链接在一起的.asm文件,Ulammtst和Ulam,Ulam进行计算并显示结果,而Ulammtst从用户处获取n值并将其发送给Ulam。getint和putint是asm文件,允许更轻松地输入/输出整数,这不是问题(因为我没有编写它们,它们来自我的教授)
另外,我想这可能是我如何初始化cx进行计数的,我觉得我可能在Ulam.asm中做了错事,但是,正如我所说,我不确定
乌拉姆斯特:
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
这是当我为n输入1时得到的结果,在稍微修改代码后,现在我在下面得到这个结果,\uu
持续闪烁
您的
ulam
例程在堆栈上推两个字,但从不弹出任何内容,这将在最后破坏ret
。那么我如何在代码中实现pop?pop是使用pop
指令实现的。它与push
正好相反。因此,我必须弹出ax和弹出cx才能在算法中使用它们?看看当前的代码,您确实需要idiv cx
。因为您刚才在几条语句中将cx设置为0,所以这不就是除以0吗?事实上,既然您使用的是cx,那么这不是将DX:AX除以cx吗?看看你刚才放在dx里的东西,也许你是指cl?您是否尝试过使用调试器单步执行此操作?
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