gpt4 book ai didi

c - 在 Assembly x86 中获取三个数字的最大值时出现段错误

转载 作者:行者123 更新时间:2023-11-30 18:41:20 26 4
gpt4 key购买 nike

我试图使用 C 来调用 Assembly 32 位 AT&T 中的方法来获取三个数字的最大值。当程序运行时,我收到段错误(核心转储)错误,并且无法弄清楚原因。我的输入是正数/负数和 1、2、3 的混合,结果都具有相同的错误。

组装

# %eax - first parameter
# %ecx - second parameter
# %edx - third parameter

.code32
.file "maxofthree.S"
.text
.global maxofthree
.type maxofthree @function

maxofthree:
pushl %ebp # old ebp
movl %esp, %ebp # skip over
movl 8(%ebp), %eax # grab first value
movl 12(%ebp), %ecx # grab second value
movl 16(%ebp), %edx # grab third value
#test for first
cmpl %ecx, %eax # compare first and second
jl firstsmaller # first smaller than second, exit if
cmpl %edx, %eax # compare first and third
jl firstsmaller # first smaller than third, exit if
leave # reset the stack pointer and pop the old base pointer
ret # return since first > second and first > third
firstsmaller: # first smaller than second or third, resume comparisons
#test for second and third against each other
cmpl %edx, %ecx # compare second and third
jg secondgreatest # second is greatest, so jump to end
movl %eax, %edx # third is greatest, move third to eax
leave # reset the stack pointer and pop the old base pointer
ret # return third
secondgreatest: # second > third
movl %ecx, %eax #move second to eax
leave # reset the stack pointer and pop the old base pointer
ret # return second

C代码

#include <stdio.h>
#include <inttypes.h>
long int maxofthree(long int, long int, long int);

int main(int argc, char *argv[]) {
if (argc != 4) {
printf("Missing command line arguments. Instructions to"
" execute this program:- .\a.out <num1> <num2> <num3>");
return 0;
}

long int x = atoi(argv[1]);
long int y = atoi(argv[2]);
long int z = atoi(argv[3]);
printf("%ld\n", maxofthree(x, y, z)); // TODO change back to (x, y, z)
}

最佳答案

该代码导致段错误,因为在执行 ret 指令时它试图跳回到无效的返回地址。所有三个不同的 ret 指令都会发生这种情况。

发生这种情况的原因是因为您在返回之前没有弹出旧的基指针。对代码进行小的更改即可消除该错误。将每个 ret 指令更改为:

leave
ret

leave 指令将执行以下操作:

movl %ebp, %esp
popl %ebp

这将重置堆栈指针并弹出您保存的旧基指针。

此外,您的比较没有按照注释中指定的方式进行。当你这样做时:

cmp %eax, %edx
jl firstsmaller

%edx小于%eax时发生跳转。所以你希望代码是

cmpl %edx, %eax
jl firstsmaller

%eax 小于 %edx 时将跳转,如注释中所指定。

引用这个this page有关 AT&T/GAS 语法中 cmp 指令的详细信息。

关于c - 在 Assembly x86 中获取三个数字的最大值时出现段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22292548/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com