Assembly 无限循环x86程序集

Assembly 无限循环x86程序集,assembly,x86,Assembly,X86,因此,我试图创建一个程序,使用提供给我的伪代码模拟Collatz序列,每行打印5个数字。我设法将代码写入x86汇编代码,但是当我编译并运行时,我没有得到想要的结果。相反,我被要求输入(这是正确的),我得到一个252521的无限循环。我不明白为什么我认为这可能是我将n(整数)传递给每个进程的方式;然而,我以前从未做过这样的编码,因为我对汇编相当陌生。我在64位win8上使用TASM(如果有帮助的话) 我有2个链接在一起的.asm文件,Ulammtst和Ulam,Ulam进行计算并显示结果,而Ula

因此,我试图创建一个程序,使用提供给我的伪代码模拟Collatz序列,每行打印5个数字。我设法将代码写入x86汇编代码,但是当我编译并运行时,我没有得到想要的结果。相反,我被要求输入(这是正确的),我得到一个252521的无限循环。我不明白为什么我认为这可能是我将
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