【问题标题】:x86 Program Freeze [tasm]x86 程序冻结 [tasm]
【发布时间】:2015-01-11 20:08:41
【问题描述】:

我有这个代码 (having a string of length n, build another of length n-2 as it follows: sir2[i]=(sir[i]+sir[i+1]+sir[1+2])/3),但我不知道它为什么会冻结。没有错误,我已经调试了一段时间,但我无法确定问题是否出在算法上。

prints macro number
local  decompose, pops
    mov bx,10
    mov al, number
    mov cx,0
    decompose:  ;pushing digits to the stack
        inc cx
        mov ah,0
        div bl
        mov dl,ah   ; remainder - last digit
        add dx,48   ; to transform it in its char version
        push dx
        cmp al,0
        jnz decompose
    pops:               ; pop digits off the stack
        pop dx
        mov ah,2h
        int 21h
    loop pops
        ; pretty spacing
        mov dl,' '
        mov ah,2h
        int 21h

endm

data segment para public 'data'
    sir db 5, 10, 12, 4, 3
    n equ $-sir
    sir2 db n-2 dup(0)
data ends

code segment para public 'code'
start proc far
    assume cs:code,ds:data
    push ds
    xor ax,ax
    push ax
    mov ax,data
    mov ds,ax

    mov si,0
    mov dx,3
    mov cx,n
    sub cx,2

l1:
    mov ah,0
    mov al,sir[si]
    add al,sir[si+1]
    add al,sir[si+2]    ;sum of 3 numbers
    div dx                  ;sir2[i]=(sir[i]+sir[i+1]+sir[1+2])/3
    mov sir2[si],al
    inc  si
    cmp si,cx
jbe l1

    mov si,0
l2:
   prints sir2[si]
    inc si
loop l2

ret
start endp
code ends
end start

谁能帮忙?

【问题讨论】:

  • 你做了哪些努力来发现它为什么会冻结以及你被困在哪里?换句话说,您是否调试过您的代码?该站点不是免费的调试服务,因此就您的问题而言,它很可能会因为离题而关闭。
  • 是的,我做到了 + 我以为我陷入了循环,所以我将其更改为 jmp。
  • 你在 decompose 例程中清除了 CX !!!将mov cx,0 更改为mov ah,0
  • 我不小心写了 CX 而不是 AH。谢谢。
  • 如果它现在有效,那么请给所有帮助过你的人投票。

标签: assembly tasm


【解决方案1】:

改变

div dx                  ;sir2[i]=(sir[i]+sir[i+1]+sir[1+2])/3

div dl                  ;sir2[i]=(sir[i]+sir[i+1]+sir[1+2])/3

(见迈克尔的回答)。

宏是一段代码,它“按原样”插入到调用宏的位置。宏 prints 更改了 CXloop l2 需要保持不变。重写循环:

    mov si, 0
    mov di, cx
l2:
    prints sir2[si]
    inc si
    dec di
    jnz l2

顺便说一句:不要忘记定义堆栈:

_STACK SEGMENT PARA STACK 'STACK'
    dw  1024 dup (?)
_STACK ENDS

【讨论】:

  • 可以写cmp si,n-2吗?
  • @LorenaSfăt:是的。 TASM 在编译时将n-2 翻译成一个常数。
  • 好的,所以现在我认为它一定是算法,因为它会打印一些值(不是正确的值),然后它会冻结......
  • @LorenaSfăt:它在这里工作。也许你应该定义一个堆栈。我相应地编辑了我的答案。
  • @LorenaSfăt:您的第二版宏 Prints 中有错误。第一个版本运行良好。
【解决方案2】:

DIV r/m16 的描述是DX:AX 除以r/m16 的无符号数”。换句话说,分子是由DXAX 中的位组合而成的32 位值。
如果商变得太大而无法容纳AX,则会出现异常。为避免这种情况,您应该在除法之前清除DX(即mov dx,0xor dx,dx)。显然这也意味着你不能使用DX 作为分母。

【讨论】:

    【解决方案3】:

    您的程序可能会因为迭代次数过多而冻结!

    cmp si,cx
    jbe l1
    

    这给出了 4 次迭代,而 sir2 只有 3 个字节的存储空间!使用jb l1

    【讨论】:

    • 我希望就是这样。我按照你们所有人所说的做了,现在它打印出值(不是正确的值),然后它就冻结了。
    • 我希望该程序仅在 ret 上退出,那么您应该删除 push dspush ax 指令。或者使用mov ah,4Chint 21h 作为程序的最后一步。
    • 但是老师说这是.exe程序的一部分,我们应该照原样处理:/
    • 您可能希望在原始问题中发布每个人建议的所有更改作为编辑,以便我们验证您是否正确执行。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多