我不明白我进行比较的方式有什么问题 (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
。
老实说,我不明白我的程序有什么问题。它将 -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
。