NASM汇编代码段错误修复求助:Linux与在线编译器均报错
修复NASM汇编代码的段错误问题
以下NASM汇编代码在在线编译器运行时提示command terminated by signal 11,Linux本地运行时输出Enter the side of theSegmentation fault且行被截断,触发段错误:
section .data ; данные msg1 db "Enter the side of the square: ", 0xA ; приглашение для ввода стороны квадрата msg2 db "Square area: S = ", 0xA ; вывод площади квадрата section .bss ; переменные a resd 1 ; переменная для стороны квадрата S resd 1 ; переменная для площади квадрата section .text ; код global _start ; стартовая точка программы _start: ; Вывод приглашения для ввода стороны квадрата mov eax, 4 ; системный вызов write mov ebx, 1 ; вывод в консоль mov ecx, msg1 ; адрес строки mov edx, 21 ; длина строки int 0x80 ; вызов ; Ввод стороны квадрата mov eax, 3 ; системный вызов read mov ebx, 0 ; ввод с
错误原因分析
- 代码不完整:
read系统调用的参数未写完,缺少输入缓冲区地址(ecx寄存器)和读取字节数(edx寄存器)的设置,直接执行int 0x80会导致寄存器值非法,访问无效内存触发段错误。 - 字符串长度错误:
msg1的实际长度为28(包含换行符),原代码手动设置的21导致输出截断。 - 关键逻辑缺失:没有将输入的ASCII字符转换为整数、计算面积、将结果转回ASCII字符串输出的逻辑,也没有正确的程序退出调用,执行到未定义内存区域触发段错误。
修复后的完整代码
section .data msg1 db "Enter the side of the square: ", 0xA msg1_len equ $ - msg1 ; 自动计算字符串长度,避免手动计数错误 msg2 db "Square area: S = " msg2_len equ $ - msg2 newline db 0xA section .bss a resd 1 ; 存储输入的边长(整数) input_buf resb 4; 存储输入的ASCII字符串 S_str resb 10 ; 存储面积的ASCII字符串 section .text global _start _start: ; 输出输入提示 mov eax, 4 mov ebx, 1 mov ecx, msg1 mov edx, msg1_len int 0x80 ; 读取用户输入(最多4字节,包含换行) mov eax, 3 mov ebx, 0 mov ecx, input_buf mov edx, 4 int 0x80 ; 将ASCII字符串转换为整数存入a mov ecx, 0 ; 计数器 mov eax, 0 convert_loop: mov bl, [input_buf + ecx] cmp bl, 0xA ; 遇到换行符停止转换 je convert_done sub bl, '0' ; ASCII字符转数字 imul eax, 10 ; 结果乘10,准备拼接下一位 add eax, ebx inc ecx jmp convert_loop convert_done: mov [a], eax ; 计算面积:边长的平方 mov eax, [a] imul eax, eax mov [S_str], eax ; 将整数转换为ASCII字符串 mov eax, [S_str] mov ecx, S_str + 9 ; 从字符串末尾开始填充 mov ebx, 10 to_ascii_loop: xor edx, edx div ebx add dl, '0' mov [ecx], dl dec ecx test eax, eax jnz to_ascii_loop ; 输出面积提示文本 mov eax, 4 mov ebx, 1 mov ecx, msg2 mov edx, msg2_len int 0x80 ; 输出面积数值 mov eax, 4 mov ebx, 1 mov ecx, ecx + 1 ; 指向第一个非空数字字符 mov edx, S_str + 9 - ecx int 0x80 ; 输出换行 mov eax, 4 mov ebx, 1 mov ecx, newline mov edx, 1 int 0x80 ; 正确退出程序 mov eax, 1 mov ebx, 0 int 0x80
核心修复点
- 使用
equ $ - msg1自动计算字符串长度,避免手动计数错误。 - 补全
read系统调用的完整参数,指定输入缓冲区和读取字节数。 - 添加ASCII与整数的互转逻辑,处理输入输出的格式转换。
- 补全面积计算逻辑和程序退出调用,确保程序执行流程完整。
内容的提问来源于stack exchange,提问作者n1rut
相关产品推荐
相关产品推荐

