无限循环x86组装

时间:2015-03-17 16:34:35

标签: assembly x86

所以我正在尝试使用给我的伪代码创建一个模拟The Collat​​z 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时得到的结果,稍微修改我的代码后,现在我得到以下结果,_持续闪烁 enter image description here

0 个答案:

没有答案