编译NASM汇编程序后出现“No such file or directory”错误求助
问题解决与代码修正
一、解决运行报错问题
你遇到的bash: ./a.out: No such file or directory错误,根源是动态链接器路径不匹配:
file命令显示程序的解释器是/lib/ld64.so.1,这是类BSD系统的链接器路径,而你的Linux系统使用的是/lib64/ld-linux-x86-64.so.2。- 解决方法:
- 用
gcc代替ld进行链接,它会自动处理正确的链接器和依赖:nasm -f elf64 program.asm -o program.o gcc program.o -o program - 或者手动指定链接器路径给
ld:ld -m elf_x86_64 -lc -dynamic-linker /lib64/ld-linux-x86-64.so.2 program.o -o program
./program即可正常执行。 - 用
二、代码逻辑修正
你的代码目前存在多处错误,无法正确读取负浮点数并计算绝对值,以下是修正后的完整代码及说明:
修正后的代码
extern printf, exit section .data numar dq 0.0 formatare db "输入的数的绝对值: %f", 10, 0 prompt db "请输入负浮点数(输入'A'结束):", 10, 0 ten dq 10.0 point_flag db 0 ; 标记是否遇到小数点 decimal_scale dq 1.0 ; 小数部分的缩放因子(10^n) section .bss buffer resb 1 negativ resb 1 section .text global main main: ; 打印提示信息 mov rdi, prompt call printf mov byte [negativ], 0 mov byte [point_flag], 0 movsd xmm0, qword [numar] movsd qword [numar], xmm0 read_loop: ; 读取一个字符 mov rax, 0 mov rdi, 0 mov rsi, buffer mov rdx, 1 syscall cmp byte [buffer], 'A' je calculate_abs cmp byte [buffer], '-' je set_negativ cmp byte [buffer], '.' je set_decimal_point ; 处理数字字符 sub byte [buffer], '0' movzx rbx, byte [buffer] cvtsi2sd xmm1, rbx ; 将整数转为双精度浮点数 cmp byte [point_flag], 0 je handle_integer_part jmp handle_decimal_part handle_integer_part: ; numar = numar * 10 + digit movsd xmm0, qword [numar] mulsd xmm0, qword [ten] addsd xmm0, xmm1 movsd qword [numar], xmm0 jmp read_loop handle_decimal_part: ; numar = numar + digit / (10^n),先更新缩放因子 mulsd qword [decimal_scale], qword [ten] ; digit / decimal_scale divsd xmm1, qword [decimal_scale] addsd xmm0, xmm1 movsd qword [numar], xmm0 jmp read_loop set_negativ: mov byte [negativ], 1 jmp read_loop set_decimal_point: mov byte [point_flag], 1 jmp read_loop calculate_abs: ; 如果是负数,取绝对值 cmp byte [negativ], 1 jne print_result movsd xmm0, qword [numar] pxor xmm1, xmm1 comisd xmm0, xmm1 jnl print_result ; 已经是正数,无需处理 subsd xmm1, xmm0 ; 0 - numar = |numar| movsd qword [numar], xmm1 print_result: mov rdi, formatare movsd xmm0, qword [numar] mov rax, 1 call printf ; 退出程序 mov rdi, 0 call exit
关键修正点
- 入口改为
main:用gcc链接时,main是标准入口,比_start更方便处理C库依赖。 - 浮点数处理逻辑:
- 区分整数部分和小数部分,使用SSE指令(
movsd、mulsd、addsd等)处理双精度浮点数,而非错误的整数乘法操作。 - 添加小数点标记,处理小数部分的缩放计算。
- 区分整数部分和小数部分,使用SSE指令(
- 绝对值计算:通过比较浮点数与0的大小,若为负数则用0减去该数得到绝对值,符合x86_64的浮点数处理规范。
- 正确的退出方式:调用
exit函数而非直接syscall,确保C库资源正常释放。
三、编译运行验证
- 编译链接:
nasm -f elf64 program.asm -o program.o gcc program.o -o program - 运行:
./program - 测试输入:比如输入
-123.45A,程序会输出输入的数的绝对值: 123.450000。
内容的提问来源于stack exchange,提问作者Oreoezi
相关产品推荐
相关产品推荐

