AT&T x86组件中的函数计算最大值

问题描述 投票:1回答:2

我正在尝试编写名为maxmax的函数,该函数将从数字列表中返回最大值,我想使用可以指示从何处开始的标签。当地址(我用于计算下一个值的位置)将超出列表时,函数将跳至循环的末尾。

不幸的是,在组装程序并运行之后,我遇到了分段错误。

我要在代码中查找错误。我尝试使用GDB调试器,但仍然无法使用。

.section .data
list_1:
 .long 5,3,6,2,7,78
list_2:
 .long 33,23,52,6,7,89,22,33,6
list_3:
 .long 22,33,10,45,6,34
end_list_3:

 .section .text

 .globl _start
 .globl maximum
_start:

 pushl list_2
 pushl list_1
 call maximum
 addl $8, %esp
 movl %eax, %ebx


 mov $1, %eax
 int $0x80
                        #maximum function: 1 param - location of first value
                        #                  2 param - location of last value+4
 .type maximum STT_FUNC
maximum:
 pushl %ebp
 movl %esp, %ebp

 movl 8(%ebp),%ebx      # %ebx = location of first value
 movl 12(%ebp), %ecx    # %ecx location of last value + 4

 movl (%ebx), %eax      # %eax will store current highest value

 movl $0, %esi          # %esi will be our index

start_loop:
 incl %esi
 lea (%ebx,%esi,4), %edx
 cmpl %edx, %ecx
 je exit_loop
 movl (%ebx,%esi,4), %edi       #%edi is a current examined value
 cmpl %eax, %edi
 cmovg %edi, %eax
 jmp start_loop
exit_loop:

 movl %ebp, %esp
 popl %ebp
 ret
assembly x86 att
2个回答
3
投票
pushl list_2 pushl list_1

list_1和list_2被视为将被压入堆栈的值的地址,因此这压入的是内存源操作数,而不是立即数。

相反,使用:

pushl $list_2 pushl $list_1

在进行了较小的更改之后,程序按计划运行,现在,这2条指令将直接地址推入:list_1和list_2,这正是我想要的。

谢谢@JérômeRichard和@Jester。    

0
投票
段错误位于此行:

mov (%ebx), %eax

这很正常,因为ebx中存储的值是整数(5),并且不是有效的指针。在以下说明中,您可能想使用lea而不是movl:

    movl 8(%ebp),%ebx      # %ebx = location of first value
    movl 12(%ebp), %ecx    # %ecx location of last value + 4
© www.soinside.com 2019 - 2024. All rights reserved.