将用户输入的数字与值 (EBX) 进行比较

Compare a number that is entered by the user to a value (EBX)

我想将用户输入并保存在堆栈中的值与我制作的常数进行比较。这些常量称为 minmax

用户输入的数字保存在一个名为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