汇编实现两数相加出现段错误,求排查与修复方案
汇编代码段错误与输出异常排查修复
我来帮你搞定这段两数相加的汇编代码问题,你的代码主要因为系统调用参数混淆、数值未转ASCII、缺少正确退出逻辑这几个点导致了段错误和预期外的输出,下面一步步拆解问题并给出修复方案:
核心错误分析
- 系统调用参数完全搞反了:Linux 32位下使用
int 0x80调用系统函数时,sys_write(输出)的规范是:eax = 4(系统调用编号)ebx = 1(标准输出stdout的文件描述符)ecx = 要输出的缓冲区地址edx = 输出内容的长度
你把这些寄存器的用途全搞混了,这是触发段错误的主要原因。
- 数值未转换为ASCII字符:你计算得到的
13是二进制数值,直接输出内存里的原始值会显示乱码,必须把数值转换成对应的ASCII字符(比如1→'1',3→'3')才能正常显示。 - 缺少程序退出逻辑:代码最后没有执行
sys_exit系统调用,程序会继续执行后续非法指令,引发错误。 - section拼写不规范:
segment .bss虽然部分汇编器兼容,但标准写法是section .bss,统一写法能避免兼容性问题。
修复后的完整代码
section .text global _start _start: ; 将字符形式的数字转为数值并相加 mov edx, '6' sub edx, '0' mov ecx, '7' sub ecx, '0' add edx, ecx ; edx = 6+7 = 13 ; 将数值13转换为ASCII字符,存储到math_sum缓冲区 mov eax, edx mov ebx, 10 div ebx ; eax=1(十位),edx=3(个位) add eax, '0' ; 把十位数值转为ASCII字符'1' mov [math_sum], eax add edx, '0' ; 把个位数值转为ASCII字符'3' mov [math_sum+1], edx ; 输出提示信息 mov eax, 4 ; sys_write的系统调用号 mov ebx, 1 ; 指向标准输出 mov ecx, msg ; 提示字符串的地址 mov edx, len ; 提示字符串的长度 int 0x80 ; 输出计算结果 mov eax, 4 mov ebx, 1 mov ecx, math_sum ; 存储ASCII结果的缓冲区地址 mov edx, 2 ; 结果是两位数,长度为2 int 0x80 ; 输出换行(让终端显示更整洁) mov eax, 4 mov ebx, 1 mov ecx, newline mov edx, 1 int 0x80 ; 正常退出程序 mov eax, 1 ; sys_exit的系统调用号 mov ebx, 0 ; 退出码0表示正常退出 int 0x80 section .data msg db "Sum of 6 and 7 is:" len equ $ - msg newline db 0xA ; 换行符的ASCII码 section .bss math_sum resb 2 ; 预留2字节空间存储两位ASCII数字
修复点说明
- 修正系统调用参数:严格按照Linux 32位系统调用规范设置寄存器,确保
sys_write和sys_exit调用合法,彻底解决段错误。 - 数值转ASCII处理:通过除法分离十位和个位,分别加上
'0'转换成ASCII字符,这样输出的是可读的数字,而不是乱码。 - 添加换行输出:新增换行符让提示信息和结果在终端显示更清晰,属于优化项但提升用户体验。
- 规范section关键字:统一使用
section替代segment,保证代码在不同汇编器下的兼容性。 - 添加正确退出逻辑:程序结束时执行
sys_exit调用,避免后续非法操作引发的错误。
内容的提问来源于stack exchange,提问作者Mactin
相关产品推荐
相关产品推荐

