函数计算 AT&T x86 汇编中的最大值
Function calculating maximum value in AT&T x86 assembly
我正在尝试编写这个名为 maximum 的函数,它将 return 数字列表中的最大值,我想使用可以指示从哪里开始的标签。当地址(我用来计算下一个值的位置)超出列表时,函数将跳转到循环的末尾。
不幸的是,在组装程序后 运行 我遇到了分段错误。
我要求找出我的代码中的错误。我尝试使用 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 , %esp
movl %eax, %ebx
mov , %eax
int [=10=]x80
#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 [=10=], %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
您可以使用调试器轻松找到原因。我建议您使用 gdb(尤其是使用 layout asm
和 ni
命令)。
段错误位于这一行:
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
问题在于推送参数,我想推送标签地址但使用的是:
pushl list_2
pushl list_1
list_1 和 list_2 被视为将被压入堆栈的值的地址,因此这是压入内存源操作数而不是立即数。
改为使用:
pushl $list_2
pushl $list_1
在那个小改动之后程序按计划运行,现在这 2 条指令推送直接地址:list_1 和 list_2,这正是我想要的。
谢谢@Jérôme Richard 和@Jester。
我正在尝试编写这个名为 maximum 的函数,它将 return 数字列表中的最大值,我想使用可以指示从哪里开始的标签。当地址(我用来计算下一个值的位置)超出列表时,函数将跳转到循环的末尾。
不幸的是,在组装程序后 运行 我遇到了分段错误。
我要求找出我的代码中的错误。我尝试使用 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 , %esp
movl %eax, %ebx
mov , %eax
int [=10=]x80
#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 [=10=], %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
您可以使用调试器轻松找到原因。我建议您使用 gdb(尤其是使用 layout asm
和 ni
命令)。
段错误位于这一行:
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
问题在于推送参数,我想推送标签地址但使用的是:
pushl list_2
pushl list_1
list_1 和 list_2 被视为将被压入堆栈的值的地址,因此这是压入内存源操作数而不是立即数。
改为使用:
pushl $list_2
pushl $list_1
在那个小改动之后程序按计划运行,现在这 2 条指令推送直接地址:list_1 和 list_2,这正是我想要的。
谢谢@Jérôme Richard 和@Jester。