我不明白我进行比较的方式有什么问题 (cmpl)

I don't understand what's wrong with the way I'm doing comparison (cmpl)

老实说,我不明白我的程序有什么问题。它将 -5 打印为数组中的最大值。当然,这是完全错误的。应该是34。我认为问题肯定出在这里:

            cmpl        %ebx, %eax                 # Compare max and value
            cmova       %eax, %ebx                 # If eax > ebx, it's new max

我认为我进行比较的方式有问题。这是本书中的一个稍微修改过的例子:Professional Assembly Language by Richard Blum (2005)

/******************************************************************************
 * max.s                                                                      *
 * =====                                                                      *
 *                                                                            *
 * Assembler: the GNU Assembler                                               *
 *                                                                            *
 *                                                                            *
 *                                                                            *
 * Description:                                                               *
 *                                                                            *
 * This program finds the largest integer in a series defined in an array.    *
 *                                                                            *
 ******************************************************************************/

# Constants
.equ DATA_SIZE,    4 # The size in bytes of each element in the array
.equ ARRAY_LENGTH, 6 # The length of the array
.equ EXIT_SUCCESS, 0 # The exit status code 0 means successful execution


.globl _start

################################################################################

.section   .data
msg:       .asciz       "Largest value is %d\n"    # Output string
a:         .long        10, -5, -45, 4, 34, 6      # Array of 6 elements


################################################################################

.section   .text
_start:     movl        a, %ebx                    # Save first element as max
            movl        , %edi                   # Start iterating at index 1
loop:       movl        a(, %edi, DATA_SIZE), %eax # Load the value
            cmpl        %ebx, %eax                 # Compare max and value
            cmova       %eax, %ebx                 # If eax > ebx, it's new max
            inc         %edi                       # Increment the index
            cmpl        $ARRAY_LENGTH, %edi        # If not reached the end,
            jne         loop                       # keep looping

            # Print the result
            pushl       %ebx                       # Second argument
            pushl       $msg                       # First argument
            call        printf                     # Call C's printf function
            addl        , %esp                   # Clean the stack

            # Exit the program
            pushl       $EXIT_SUCCESS              # Exit status code
            call        exit                       # Call C's exit function

要编译程序,请使用此命令:

as --32 -gstabs max.s -o max.o && \
ld -m elf_i386 -dynamic-linker /lib/ld-linux.so.2 -o a.out -lc max.o && \
rm max.o && ./a.out

正如有人所说,cmova 检查 "above",它将值视为 unsigned。如果您将数字视为 unsigned-5 将被解释为 0xFFFFFFFB,这远高于 34(也高于 -45,或者0xFFFFFFD3)。因此该值 "wins",并再次显示为 signed 数字(即 -5)。

如果要比较有符号数,请改用 cmovg