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保存之前的值,使用它,然后恢复之前的值。您可以使用 push
和 pop
指令执行此操作:
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 的东西,其中规定了哪些寄存器将被您调用的其他函数保存和恢复。这些被写下来作为每个人都遵循的规则,以便可以在不同的编译器和语言之间调用代码而不会覆盖寄存器值。
所以我的任务是创建一个由星号 (*) 组成的 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保存之前的值,使用它,然后恢复之前的值。您可以使用 push
和 pop
指令执行此操作:
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 的东西,其中规定了哪些寄存器将被您调用的其他函数保存和恢复。这些被写下来作为每个人都遵循的规则,以便可以在不同的编译器和语言之间调用代码而不会覆盖寄存器值。