简体   繁体   中英

Assembly x86 call after cmp

I have the following code to compare numbers and increment a variable if true or false

failcheck1:
            mov eax, val1
            add ebx, 4
            cmp eax, 40
            jl failinc1

            mov eax, passes
            inc eax
            mov passes, eax
            jmp failcheck2

failinc1:
            mov eax, fails
            inc eax
            mov fails, eax


failcheck2 :
            mov eax, val2
            add ebx, 4
            cmp eax, 40
            jl failinc2

            mov eax, passes
            inc eax
            mov passes, eax
            jmp failcheck3

failinc2:
            mov eax, fails
            inc eax
            mov fails, eax

I have 8 such checks. I was wondering if I create a single failinc and passinc subroutine with ret in it how can I call it after cmp ?

Because EBX is independantly incrementing, you can replace the 8 add ebx, 4 by a single addition add ebx, 4*8 .

You can avoid all of those ugly and time consuming conditional jumps by using the conditional set instruction setl (Set On Less).

Because fails and passes are mutually exclusive, you can defer from calculating the passes to the very end. eg If processing 8 values gave 3 fails then there inevitably have to be 5 passes (is 8 minus 3).

 xor  ecx, ecx    ;Clear because SETL only operates on a byte
 xor  edx, edx    ;Clear temporary counter of fails

 cmp  val1, 40
 setl cl
 add  edx, ecx    ;Conditionally increment temporary counter
 cmp  val2, 40
 setl cl
 add  edx, ecx    ;Conditionally increment temporary counter
 cmp  val3, 40
 setl cl
 add  edx, ecx    ;Conditionally increment temporary counter
 cmp  val4, 40
 setl cl
 add  edx, ecx    ;Conditionally increment temporary counter
 cmp  val5, 40
 setl cl
 add  edx, ecx    ;Conditionally increment temporary counter
 cmp  val6, 40
 setl cl
 add  edx, ecx    ;Conditionally increment temporary counter
 cmp  val7, 40
 setl cl
 add  edx, ecx    ;Conditionally increment temporary counter
 cmp  val8, 40
 setl cl
 add  edx, ecx    ;Conditionally increment temporary counter

 add  fails, edx  ;Add temporary counter to actual variable
 sub  edx, 8
 sub  passes, edx ;Add complementary count to other variable (*)

 add  ebx, 4*8

I was wondering if I create a single failinc and passinc subroutine with ret in it how can I call it after cmp ?

Now the subroutine

AddTempCount:     ;On input EFLAGS is set from CMP instruction
 setl cl
 add  edx, ecx    ;Conditionally increment temporary counter
 ret

can improve the readability a bit.

 xor  ecx, ecx    ;Clear because SETL only operates on a byte
 xor  edx, edx    ;Clear temporary counter of fails

 cmp  val1, 40
 call AddTempCount
 cmp  val2, 40
 call AddTempCount
 cmp  val3, 40
 call AddTempCount
 cmp  val4, 40
 call AddTempCount
 cmp  val5, 40
 call AddTempCount
 cmp  val6, 40
 call AddTempCount
 cmp  val7, 40
 call AddTempCount
 cmp  val8, 40
 call AddTempCount

 add  fails, edx  ;Add temporary counter to actual variable
 sub  edx, 8
 sub  passes, edx ;Add complementary count to other variable (*)

 add  ebx, 4*8

(*) Subtracting a negative count is the same as adding a positive count.

failcheck:
    mov eax, [eax]
    add ebx, 4
    cmp eax, ecx
    jl .L1
    incl passes
    ret
.L1:
    incl fails
    ret

failcheck1:
    lea eax, val1
    mov ecx, 40
    call failcheck

    lea eax, val2
    mov ecx, 40
    call failcheck

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM