将用户输入的数字与值 (EBX) 进行比较
Compare a number that is entered by the user to a value (EBX)
我想将用户输入并保存在堆栈中的值与我制作的常数进行比较。这些常量称为 min
和 max
。
用户输入的数字保存在一个名为Num
的变量中,该变量位于堆栈的ebp+8
中。我想使用 cmp
将该值与常量进行比较,以便检查数字是否在允许的范围内。
已提供问题图片。The problem.
TITLE template
INCLUDE Irvine32.inc
min = 10
max = 200
lo = 100
hi = 999
.data
ask BYTE "How many numbers should be generated? [10 .. 200]: ",0
Num DWORD ?
wrong BYTE "Invalid input",0
.code
main PROC
push OFFSET Num
call getData
exit
main ENDP
getData PROC
;Set up the stack frame
push
ebp
mov ebp, esp
mov ebx, [ebp+8]
;Ask the user
again:
mov ebx, [ebp+8]
mov edx, OFFSET ask
call WriteString
call ReadDec
mov [ebx], eax
;Check the input
cmp [ebx], min
jl nono
cmp [ebx], max
jg nono
jmp okay
nono:
mov edx, OFFSET wrong
call WriteString
call CrLf
loop again
okay:
pop ebp
ret 4
getData ENDP
END main
如评论所述,您在代码中写了类似 cmp [ebx],10
的内容,这对汇编程序来说是模棱两可的(在 32b 模式下,可以从中汇编 3 条不同的指令,针对 BYTE、WORD 或 DWORD 内存大小有 3 个 [size-] 不同的立即值),所以 cmp dword ptr [ebx],10
将解决这个问题,但还有更多问题,这里是 ;*
注释中的固定代码 + 建议(带星号):
getData PROC
;Set up the stack frame
push ebp
mov ebp, esp
;Ask the user
again:
mov edx, OFFSET ask
call WriteString
call ReadDec
mov ebx, [ebp+8] ;* ebx loaded more locally to its usage
;* it's anti-performance, but makes source easier to read+check
;* and you don't need to worry about some subroutine to modify ebx
;* as it was waiting for user input, so there's no problem with performance
mov [ebx], eax
;Check the input
;* cmp dword ptr [ebx], min
;* ^ ^ ^ ^ ^ this would work, but the value is still in eax
cmp eax, min ;* so why not to compare that!
jl nono
cmp eax, max ;* also here
jg nono
;* okay, just return
pop ebp
ret 4
nono:
mov edx, OFFSET wrong
call WriteString
call CrLf
jmp again ;* JMP, not LOOP!
;* Loop will modify ECX and when ECX decreases to zero, loop will not jump
getData ENDP
其实你可以在ReadDec
之后立即检查,只有在合法范围内的值才存储,像这样:
...
call ReadDec
;Check the input
cmp eax, min
jl nono
cmp eax, max
jg nono
;* good value, store it + return
mov edx, [ebp+8] ;* and I would use EDX, already modified for WriteString
mov [edx], eax ;* so no need to modify also EBX
pop ebp
ret 4
... ; "nono:" code from above
我想将用户输入并保存在堆栈中的值与我制作的常数进行比较。这些常量称为 min
和 max
。
用户输入的数字保存在一个名为Num
的变量中,该变量位于堆栈的ebp+8
中。我想使用 cmp
将该值与常量进行比较,以便检查数字是否在允许的范围内。
已提供问题图片。The problem.
TITLE template
INCLUDE Irvine32.inc
min = 10
max = 200
lo = 100
hi = 999
.data
ask BYTE "How many numbers should be generated? [10 .. 200]: ",0
Num DWORD ?
wrong BYTE "Invalid input",0
.code
main PROC
push OFFSET Num
call getData
exit
main ENDP
getData PROC
;Set up the stack frame
push
ebp
mov ebp, esp
mov ebx, [ebp+8]
;Ask the user
again:
mov ebx, [ebp+8]
mov edx, OFFSET ask
call WriteString
call ReadDec
mov [ebx], eax
;Check the input
cmp [ebx], min
jl nono
cmp [ebx], max
jg nono
jmp okay
nono:
mov edx, OFFSET wrong
call WriteString
call CrLf
loop again
okay:
pop ebp
ret 4
getData ENDP
END main
如评论所述,您在代码中写了类似 cmp [ebx],10
的内容,这对汇编程序来说是模棱两可的(在 32b 模式下,可以从中汇编 3 条不同的指令,针对 BYTE、WORD 或 DWORD 内存大小有 3 个 [size-] 不同的立即值),所以 cmp dword ptr [ebx],10
将解决这个问题,但还有更多问题,这里是 ;*
注释中的固定代码 + 建议(带星号):
getData PROC
;Set up the stack frame
push ebp
mov ebp, esp
;Ask the user
again:
mov edx, OFFSET ask
call WriteString
call ReadDec
mov ebx, [ebp+8] ;* ebx loaded more locally to its usage
;* it's anti-performance, but makes source easier to read+check
;* and you don't need to worry about some subroutine to modify ebx
;* as it was waiting for user input, so there's no problem with performance
mov [ebx], eax
;Check the input
;* cmp dword ptr [ebx], min
;* ^ ^ ^ ^ ^ this would work, but the value is still in eax
cmp eax, min ;* so why not to compare that!
jl nono
cmp eax, max ;* also here
jg nono
;* okay, just return
pop ebp
ret 4
nono:
mov edx, OFFSET wrong
call WriteString
call CrLf
jmp again ;* JMP, not LOOP!
;* Loop will modify ECX and when ECX decreases to zero, loop will not jump
getData ENDP
其实你可以在ReadDec
之后立即检查,只有在合法范围内的值才存储,像这样:
...
call ReadDec
;Check the input
cmp eax, min
jl nono
cmp eax, max
jg nono
;* good value, store it + return
mov edx, [ebp+8] ;* and I would use EDX, already modified for WriteString
mov [edx], eax ;* so no need to modify also EBX
pop ebp
ret 4
... ; "nono:" code from above