我不明白我做比较的方式有什么不对(cmpl)

时间:2016-07-11 15:27:32

标签: assembly x86 gas

老实说,我不明白我的计划有什么问题。它将-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        $1, %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        $8, %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

1 个答案:

答案 0 :(得分:2)

有人说,cmova会检查“上方”,将值视为 unsigned 。如果您将数字视为未签名-5将被解释为0xFFFFFFFB,其远远高于34(并且也高于-45或{{1} }})。因此该值“获胜”,并再次显示为签名号码(即0xFFFFFFD3)。

如果您想比较已签名的号码,请改用-5