cmp 指令不在 InsertionSort 中进行 jge 跳转

Posted

技术标签:

【中文标题】cmp 指令不在 InsertionSort 中进行 jge 跳转【英文标题】:cmp instruction not making jge jump within InsertionSort 【发布时间】:2019-06-20 17:54:21 【问题描述】:

我正在尝试使用 MASM 编写 InsertionSort 的迭代版本。在反复出现意外错误后,我尝试逐行运行代码并在调试器中观察它是否符合我的预期。果然,我的“while 循环”中的 cmp 指令似乎并没有每次都在跳跃:

; store tmp in edx
    movzx edx, word ptr[ebx + esi * 2];   edx: tmp = A[i]
    ...
    //blah blah

while_loop :
...
    movzx eax, word ptr[ebx + 2 * edi]
    cmp dx, ax
    jge exit_while

例如,如果我使用给定的数据,在第一次“for 循环”迭代之后,我会到达 EDX=0000ABAB 和 EAX=00003333 的点。我到达了线路:

cmp dx, ax
jge exit_while

由于 ABAB>3333,我希望它跳转到 exit_while,但它没有!

这是怎么回事???我完全不知所措。

.data
arr word 3333h, 1111h, 0ABABh, 1999h, 25Abh, 8649h, 0DEh, 99h
sizeArr dword lengthof arr
printmsg byte "The array is: [ ", 0
comma byte ", ", 0
endmsg byte " ]", 0

.code
main proc
    call printArr
    call crlf
    push sizeArr
    push offset arr
    call insertionsort
    call crlf
    call printArr
    call crlf
    call exitprocess
main endp


insertionsort proc
    push ebp
    mov ebp, esp
    _arr = 8
    len = _arr + 4

    mov ebx, [ebp + _arr]
    mov ecx, [ebp + len]
    dec ecx
    mov esi, 1; store i in esi, with i=1 initially

;   for (i = 1; i < SIZE; i++)
forloop:

; store tmp in edx
    movzx edx, word ptr[ebx + esi * 2];   edx: tmp = A[i]

; store j in edi, where in initially j = i
    mov edi, esi
;set j=i-1
    dec edi

;while (j >= 0 &&   tmp<arr[j])
while_loop :
    cmp edi, 0
    jl exit_while
    movzx eax, word ptr[ebx + 2 * edi]
; cmp dx, [ebx + 2 * edi]
    cmp dx, ax
    jge exit_while

; A[j] = A[j-1]
    push word ptr [ebx+2*edi]
    pop word ptr [ebx+2*edi+2]
; j = j - 1
    dec edi
    jmp while_loop

exit_while:
    push dx
    pop word ptr[ebx + 2*edi+2]
    ; mov[ebx + edi], dx;    A[j] = tmp
    inc esi;     i = i + 1
    loop forloop

finished:
    mov esp, ebp
    pop ebp
    ret 8
insertionsort endp



printArr proc
    push ebp
    mov ebp, esp
    mov ebx, offset sizeArr
    mov ecx, [ebx]
    mov esi, offset arr
    mov edx, offset printmsg
    call writestring
    mov edx, offset comma
loop1 :
    movzx eax, word ptr [esi]
    call writeHex
    call writestring
    add esi, 2
loop loop1

    mov edx, offset endmsg
    call writestring
    mov esp, ebp
    pop ebp
    ret
printArr endp

【问题讨论】:

【参考方案1】:

jge 是有符号值的版本 - 因此,值为 ABAB 的单词是负数 - 因此您会看到比较结果。

尝试jae(如果高于或等于则跳转) - 无符号等效项。

【讨论】:

谢谢....我不敢相信这就是问题所在。 @AdamG:由于您无论如何都将 16 位值零扩展为 32 位寄存器,而不是使用 cmp ax, [ebx + 2 * edi] 或其他东西,因此使用 16 位操作数大小覆盖是没有意义的,只需使用cmp eax, edx。 (然后你的签名比较会因为某种错误的原因而起作用。)但是使用 16 位内存源操作数可能更有效。顺便说一句,是的 movzx 通常是 16 位负载的最佳选择,比使用 mov ax, [addr] 合并到现有 EAX 更好

以上是关于cmp 指令不在 InsertionSort 中进行 jge 跳转的主要内容,如果未能解决你的问题,请参考以下文章

汇编 - CMP 后的 JZ 指令

汇编语言 CMP指令

《汇编语言(第三版)》cmp指令

Android 逆向x86 汇编 ( cmp 比较指令 | test 比较指令 )

Android 逆向x86 汇编 ( cmp 比较指令 | test 比较指令 )

汇编指令之CMP, TEST指令