C调用质数测试汇编代码触发Segmentation fault (core dumped)问题求助
问题原因与解决方案
核心错误点
- 违反x86-64调用约定:原汇编代码直接修改了非易失性寄存器
ebx,但未保存和恢复其原始值。在System V AMD64调用约定中,rbx/ebx属于被调用者必须保留的寄存器,随意修改会破坏调用者(main函数)的上下文,最终触发内存访问错误。 - 质数判断逻辑完全错误:原代码错误地使用
mValue([rsi])作为除数,而非循环变量ecx,违背了原C代码“从2到m依次取除数判断整除性”的逻辑,不仅导致判断结果错误,还可能间接引发寄存器状态异常。
修正后的汇编代码
section .text global isPrime isPrime: mov ecx, 2 ; 初始化起始除数为2 .test: cmp ecx, [rsi] ; 比较当前除数与m值 jg .prime ; 除数超过m,说明是质数 ; 计算当前数除以除数的余数 mov eax, [rdi] ; 加载待判断的数值到eax mov edx, 0 ; 清空edx,保证div操作的被除数为edx:eax div ecx ; eax = 商, edx = 余数 cmp edx, 0 je .notPrime ; 余数为0,说明能整除,不是质数 ; 余数不为0,除数+1继续循环 inc ecx jmp .test .notPrime: mov eax, 1 ; 返回1表示非质数 ret .prime: mov eax, 0 ; 返回0表示是质数 ret
修正说明
- 移除了对
ebx的使用,改用循环变量ecx直接作为除数,避免破坏非易失性寄存器。 - 修正了整除判断逻辑:现在每次用当前循环的
ecx值作为除数,完全匹配原C代码的逻辑。 - 将
jle .notPrime改为je .notPrime,因为div指令产生的余数edx范围是0到除数-1,不可能为负数,用相等判断更准确。
验证结果
编译运行修正后的代码,输入10会得到正确输出:
Enter the limit of the prime numbers:10 0 Number 2 is prime 0 Number 3 is prime 1 0 Number 5 is prime 1 0 Number 7 is prime 1 1
内容的提问来源于stack exchange,提问作者Bille Ibinabo
相关产品推荐
相关产品推荐

