【问题标题】:MASM32 loopMASM32 循环
【发布时间】:2009-02-10 04:48:07
【问题描述】:

我试图在 Windows Vista 下运行的 masm32 中创建一个循环,但是我这样做了,即使它实际上完成了循环,它也会崩溃,我看不出有什么明显的原因......有什么想法吗?

.386
.model flat, stdcall
option casemap :none

include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\masm32.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\masm32.lib

.data
ProgramText db "Looping!", 0

.data?
loop_stopper   dd      ?

.code
start:

mov loop_stopper,2

loop_start:
invoke StdOut, addr ProgramText
cmp loop_stopper, 0
dec loop_stopper                 
jg loop_start

end start

编辑

做过

invoke StdOut, offset ProgramText

仍然崩溃...

【问题讨论】:

  • 尽管这是 7 年前的事,但它还是第一次出现在我的谷歌搜索中,所以我建议在底部添加 INVOKE ExitProcess, 0

标签: assembly crash masm


【解决方案1】:

您需要有一个“退出”来结束您的应用程序。另外,我个人的风格是将所有内容都放在子程序中,但这只是我自己。

类似:
.code

开始:

call main
inkey        
exit

主进程

mov loop_stopper,2
loop_start:

invoke StdOut, addr ProgramText
cmp loop_stopper, 0 
dec loop_stopper
jg loop_start
ret

主端p

结束开始

【讨论】:

    【解决方案2】:

    在我看来,您的指示顺序是错误的。您进行比较,然后递减,然后进行条件跳转。比较中的标志值可能会因减量而改变。

      loop_start:
    
      invoke StdOut, addr ProgramText
      cmp loop_stopper, 0 
      dec loop_stopper
      jg loop_start
    
      ret
    

    当我在做汇编编程时,我是这样做的:递减计数器,如果非零则循环。

     loop_start:
    
      invoke StdOut, addr ProgramText
    
      dec loop_stopper
      jnz loop_start
    
      ret
    

    当然,根据处理器的不同,您可以将循环变量放在一个寄存器中,这样您就可以使用一条指令进行递减和循环。 (例如 Z80 'djnz' 指令。我不记得它实际上是哪个寄存器,尽管 'B' 寄存器似乎敲响了警钟)。

    另外,正如其他人所建议的那样,您似乎没有清理内存空间。大多数程序实际上是对您的代码的“调用”。因此,您需要保留代码和堆栈指针,以便您可以优雅地“返回”到操作系统的调用部分。如果您还没有这样做,您的“返回”可以将您带到堆栈顶部恰好指向的任何地方,通常会带来灾难性的后果。

    【讨论】:

    • 如果一个人从零开始循环向上,当计数器达到大于零的预定值时想要停止,该怎么办?
    【解决方案3】:

    ClubPetey 是对的。 MASM 不会为您的代码生成结语。因此,处理器继续执行它在最后一条写入指令后面找到的内容。 exit 明确要求操作系统停止执行程序。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多