X86 程序正在执行条件跳转,而我不';我不知道为什么
我不熟悉汇编语言,我不知道为什么我的条件语句不能按我希望的方式执行。我认为它应该如何工作是当我在eax和-1上使用cmp时,当输入为0或更大时,程序应该跳转到非负标签,如果小于0,则应该退出程序,但无论输入如何,程序总是跳转到非负标签,并执行分配给该标签的代码。我使用的是Irvine 32X86 程序正在执行条件跳转,而我不';我不知道为什么,x86,masm,irvine32,X86,Masm,Irvine32,我不熟悉汇编语言,我不知道为什么我的条件语句不能按我希望的方式执行。我认为它应该如何工作是当我在eax和-1上使用cmp时,当输入为0或更大时,程序应该跳转到非负标签,如果小于0,则应该退出程序,但无论输入如何,程序总是跳转到非负标签,并执行分配给该标签的代码。我使用的是Irvine 32 INCLUDE Irvine32.inc .data testing BYTE "you have entered a non-negative number! ", 0 .code main PROC
INCLUDE Irvine32.inc
.data
testing BYTE "you have entered a non-negative number! ", 0
.code
main PROC
call ReadInt
cmp eax, -1
JG nonNegative
nonNegative:
mov edx, OFFSET testing
call WriteString
call CrLf
exit
main ENDP
END main
对于任何非负数,我希望程序打印“您输入了一个非负数!”,对于任何负数,我希望程序退出。相反,程序总是打印“您输入了一个非负数!”然后退出。您有以下代码:
call ReadInt ; Read the value to EAX
cmp eax, -1 ; determine JMP condition
JG nonNegative ; JMP if EAX > -1
nonNegative: ; Jump @target
mov edx, OFFSET testing ; Print message
call WriteString ; ...
call CrLf ; Print NextLine
.data
negNumber BYTE "you have entered a negative number! ", 0
zeroOrAbove BYTE "you have entered a non-negative number! ", 0
.code
call ReadInt ; Read the value to EAX
cmp eax, -1 ; determine JMP condition
JG nonNegative ; JMP if EAX > -1
; this execution path was missing in your solution
mov edx, OFFSET negNumber ; Print message
call WriteString ; ...
call CrLf ; Print NextLine
jmp fin
nonNegative: ; Jump target
mov edx, OFFSET zeroOrAbove ; Print message
call WriteString ; ...
call CrLf ; Print NextLine
fin:
问题是您将EAX中的返回值与-1
进行了正确的比较
cmp eax, -1 ; determine JMP condition
您可以使用
JG nonNegative ; JMP if EAX > -1
但您的错误是,这次跳转的JMP目标是下一行:
nonNegative: ; Jump @target
因此,如果跳转被执行(条件满足)或未被执行(条件未满足),则执行以下指令:
mov edx, OFFSET testing ; Print message
call WriteString ; ...
call CrLf ; Print NextLine
因此,在控制台上始终会得到相同的结果:
您输入了一个非负数
要提供正确的替代方案,请查看以下代码:
call ReadInt ; Read the value to EAX
cmp eax, -1 ; determine JMP condition
JG nonNegative ; JMP if EAX > -1
nonNegative: ; Jump @target
mov edx, OFFSET testing ; Print message
call WriteString ; ...
call CrLf ; Print NextLine
.data
negNumber BYTE "you have entered a negative number! ", 0
zeroOrAbove BYTE "you have entered a non-negative number! ", 0
.code
call ReadInt ; Read the value to EAX
cmp eax, -1 ; determine JMP condition
JG nonNegative ; JMP if EAX > -1
; this execution path was missing in your solution
mov edx, OFFSET negNumber ; Print message
call WriteString ; ...
call CrLf ; Print NextLine
jmp fin
nonNegative: ; Jump target
mov edx, OFFSET zeroOrAbove ; Print message
call WriteString ; ...
call CrLf ; Print NextLine
fin:
您的问题是,在这两种情况下,都会打印字符串。尽管您似乎有一个条件跳转,但这两种可能性都会导致相同的执行路径。看看它!想想看@因此,当我输入0作为我的号码时,它将存储在eax寄存器中。然后我在eax和-1上进行cmp。0不大于-1,因此如何满足跳转条件?问题不在于是否满足
Jcc
条件。问题在于,在任何一种情况下,都会执行相同的指令。因此,该值可以是-1
,0
,1
,并且在任何情况下,都会达到标签非负的,并执行以下代码。@zx485好的,那么我是否了解跳到标签的工作原理?我认为当执行条件跳转时,系统会检查条件,如果条件为真,则跳转到正确的代码。但在我的例子中,即使条件为false,它仍然跳转到代码?我一定是遗漏了什么。如果条件为false,JCC将执行下一条指令,就像NOP一样。如果大于条件不为真,您希望CPU接下来做什么?如果您没有给它一个退出
行的标签,它怎么知道跳转到哪里?