X86 程序正在执行条件跳转,而我不';我不知道为什么

X86 程序正在执行条件跳转,而我不';我不知道为什么,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

我不熟悉汇编语言,我不知道为什么我的条件语句不能按我希望的方式执行。我认为它应该如何工作是当我在eax和-1上使用cmp时,当输入为0或更大时,程序应该跳转到非负标签,如果小于0,则应该退出程序,但无论输入如何,程序总是跳转到非负标签,并执行分配给该标签的代码。我使用的是Irvine 32

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接下来做什么?如果您没有给它一个
退出
行的标签,它怎么知道跳转到哪里?