Assembly 中的意外无限循环

Accidental infinite loop in Assembly

所以我的任务是创建一个由星号 (*) 组成的 V,每个 * 都有一个随机的前景色和背景色。这是我的代码...我中断了几次并跟踪了程序,并稍微弄清楚了它的问题所在。当我 运行 它时,它变成了一个无限循环,因为反斜杠 PROC 调用了覆盖循环计数器(ECX 寄存器)并覆盖 DH/DL 用于移动光标位置的寄存器。我是组装初学者,可以使用一些提示或技巧来避免将来出现这些问题并进行修复。感谢您的帮助,在此先感谢!

分配指南 - https://docs.google.com/document/d/1iPqfTd0qNOQo_xubVvsZLqfeNDog8mK6kzGGrR6s-OY/edit?usp=sharing

 ; main.asm - Assembly language source file
 ; Author:       Dekota Brown
 ; Date:             2/21/2017
 ; Description:  Colorful V-Pattern

 INCLUDE Irvine32.inc                   ; Irvine's assembly library
 ExitProcess PROTO,dwExitCode:DWORD     ; MS Windows ExitProcess function

.data
  nullVar DWORD ?
  msgEnd BYTE "Is the program running as you thought?",0
  msgEndCaption BYTE "Program Exit...",0
  symbol BYTE '*',0
.code
main PROC                               ; main procedure, entry point

mov EAX, nullVar
mov EBX, nullVar
mov ECX, nullVar
mov EDX, nullVar

call backslash

mov EDX,OFFSET msgEnd
mov EBX,OFFSET msgEndCaption
call MsgBoxAsk


mov EAX,07
call SetTextColor
call CrLf
call WaitMsg

INVOKE ExitProcess,0                ; end the program

main ENDP

color PROC

    call Randomize  ; Seed the RNG
    mov ECX,20  ; Set up loop counter
L1:
    mov EAX, 256
    call RandomRange
    call SetTextColor
    mov EDX,OFFSET symbol
    call WriteString
loop L1

    ret
color ENDP

backslash PROC

    mov dl, 2   ; Row 2
    mov dh, 4   ; Column 4
    mov ECX,20  ; Sets up loop counter
L2:
    call color
    call CrLf
    add dh,1    ; Increments column or shifts right by 1 position 
loop L2

    ret
backslash ENDP

forwardslash PROC

    ret
forwardslash ENDP

END

很好地确定了问题所在。当遇到这个问题时(因为只有一个ECX寄存器),需要color proc保存之前的值,使用它,然后恢复之前的值。您可以使用 pushpop 指令执行此操作:

color PROC
    push ecx ; ***** save previous value
    call Randomize  ; Seed the RNG
    mov ECX,20  ; Set up loop counter
L1:
    mov EAX, 256
    call RandomRange
    call SetTextColor
    mov EDX,OFFSET symbol
    call WriteString
loop L1
    pop ecx ; ***** restore previous value
    ret
color ENDP

我已经用*****标记了添加的代码。

对于给定的平台和操作系统,有一种叫做 ABI 的东西,其中规定了哪些寄存器将被您调用的其他函数保存和恢复。这些被写下来作为每个人都遵循的规则,以便可以在不同的编译器和语言之间调用代码而不会覆盖寄存器值。