老实说,我不明白我的计划有什么问题。它将-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
答案 0 :(得分:2)
有人说,cmova
会检查“上方”,将值视为 unsigned 。如果您将数字视为未签名,-5
将被解释为0xFFFFFFFB
,其远远高于34(并且也高于-45
或{{1} }})。因此该值“获胜”,并再次显示为签名号码(即0xFFFFFFD3
)。
如果您想比较已签名的号码,请改用-5
。