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

时间:2017-11-04 23:42:44

标签: assembly x86 masm

我想将用户输入并保存在堆栈中的数据与我制作的常数进行比较。常量称为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

enter image description here

1 个答案:

答案 0 :(得分:0)

正如评论所指出的那样,你在代码中写了类似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