x86汇编分段函数实现错误求助:计算结果不符合预期
分段函数x86汇编代码修正
原问题描述
需要实现分段函数:
- 当x≤-1时,输出(-x²+1)
- 当|x|<1时,输出0
- 当x≥1时,输出(x²-1)
原代码存在两个问题:
- 输入-3时得到8而非-8
- 输入0.5时得到-0.75而非0
修正后的代码
extern printf, scanf global main section .data in_fmt db "%lf", 0 out_fmt db "Result: %lf", 10, 0 one dq 1.0 minus_one dq -1.0 section .bss x resq 1 ; 用resq更清晰,双精度浮点数占8字节 f resq 1 temp resq 1 section .text main: mov rbp, rsp; 调试用栈帧 ; 读取输入x mov rdx, x mov rcx, in_fmt sub rsp, 40 ; 对齐栈 call scanf add rsp, 40 fld qword[x] ; ST0 = x ; 判断x ≤ -1 fld qword[minus_one] ; ST0=-1, ST1=x fxch ; ST0=x, ST1=-1,交换后直接比较x和-1 fcomi st0, st1 ; 比较x和-1 jle case1 ; x ≤ -1 时跳转到case1 fstp qword[temp] ; 弹出x,此时栈空 ; 判断|x| < 1:先取绝对值,再和1比较 fld qword[x] fabs ; ST0 = |x| fld qword[one] ; ST0=1, ST1=|x| fxch ; ST0=|x|, ST1=1 fcomi st0, st1 ; 比较|x|和1 jl case2 ; |x| < 1 时跳转到case2 ; case3: x ≥1 fstp qword[temp] ; 弹出|x|,栈空 fld qword[x] fmul qword[x] ; x*x fsub qword[one] ; x² -1 fstp qword[f] jmp print case2: fldz ; 加载双精度0.0 fstp qword[f] ; 存入结果 jmp print case1: fstp qword[temp] ; 弹出x,栈空 fld qword[x] fmul qword[x] ; x*x fmul qword[minus_one] ; -x² fadd qword[one] ; -x² +1 fstp qword[f] print: mov rcx, out_fmt mov rdx, qword[f] sub rsp, 40 call printf add rsp, 40 xor rax, rax ret
关键修正点
x≤-1的判断逻辑修正
原代码中fcomi的操作数顺序颠倒,导致判断条件完全相反。通过fxch交换栈顶两个元素,让ST0为x、ST1为-1,此时fcomi st0, st1后用jle case1就能正确匹配x≤-1的条件。|x|<1的判断修正
原代码未对x取绝对值,直接比较x和1,导致正数小于1的情况错误进入case3。新增fabs指令计算x的绝对值,再和1比较,用jl case2(小于)匹配|x|<1的条件。case2的赋值修正
原代码用mov qword[f], 0直接给双精度变量赋值整数0,这会导致内存中存储的是整数0的二进制表示,而非双精度浮点数0.0的格式。改用fldz加载标准双精度0.0,再存入结果变量。注释与变量声明优化
将resb 8改为resq 1,更直观表示双精度浮点数的存储;修正case3中错误的注释,确保逻辑清晰。
内容的提问来源于stack exchange,提问作者Dan_the_Man
相关产品推荐
相关产品推荐

