NASM汇编循环实现两数乘法时出现SIGSEGV错误该如何修复
修复方案
段错误的核心原因
你代码里把call convert_values这句注释掉了,执行完mov [result], ax之后,程序会直接顺序执行落入convert_values标签的代码块。等convert_values执行到ret指令时,栈上没有对应的返回地址(只有call指令才会把下一条指令的地址压栈),ret会把栈上的随机值当成跳转地址,访问非法内存直接触发Invalid memory reference (SIGSEGV)错误。
其他需要修复的逻辑问题
- 数字转字符输出的顺序错误:你每次先打印除法的余数,最终输出的结果会是倒序,比如42*43=1806会被输出为6081。
- 字符转换操作长度不匹配:
add [remainder], word '0'是16位操作,而你存在remainder里的余数是8位的AH寄存器值,会错误修改相邻内存的值,应该改为字节操作。 - 末尾的退出逻辑永远执行不到:
convert_values执行完返回后,你没有加退出逻辑,程序会继续往下执行print_char的代码,引发未知错误。
修复后的完整代码
;nasm 2.13.02 section .bss result: resb 2 num1: resb 2 num2: resb 2 quotient: resb 2 remainder: resb 2 section .text global _start _start: mov [num1], word 0x2A ;存42到num1 mov [num2], word 0x2B ;存43到num2 (42*43=1806) mov al, [num1] mov bl, [num2] mul bl mov [result], ax call convert_values ; 输出换行 mov eax,4 mov ebx,1 mov ecx,0xa push ecx mov ecx,esp mov edx,1 int 80h add esp,4 ; 正常退出 mov eax,1 mov ebx,0 int 80h ; 调整转换逻辑,用栈暂存余数解决输出倒序问题 convert_values: mov cx,0 ; cx做计数器,记录存储的位数 mov ax, [result] convert_loop: mov bl, 10 div bl ; 除10,AL=商 AH=余数 add ah, '0' ; 余数直接转ASCII push ax ; 压栈存储,利用栈先进后出的特性矫正顺序 inc cx xor ah,ah ; 清空AH,下次除法用AX存商 or ax,ax jnz convert_loop ; 从栈弹出字符打印,顺序就是正的 print_loop: pop ax mov [remainder], ah mov eax,4 mov ebx,1 mov ecx,remainder mov edx,1 int 80h dec cx jnz print_loop ret
编译运行测试命令
nasm -f elf32 multiply.asm -o multiply.o ld -m elf_i386 multiply.o -o multiply ./multiply
运行后会正常输出1806。
内容的提问来源于stack exchange,提问作者jR10sMX
相关产品推荐
相关产品推荐

