汇编程序循环第二次迭代崩溃问题排查求助
汇编程序段错误排查:循环读取输入并存入数组计算总和
我刚接触汇编语言,编写了一个程序,要求循环5次读取用户输入的数字,将ASCII转换为整数存入intArray数组,同时计算这些数字的总和。代码可以编译链接,但执行到第二次迭代时出现段错误,报错信息如下:
Enter an integer: 49
Enter an integer: 50
zsh: segmentation fault out/solution
以下是我的代码,请帮忙排查问题:
section .bss input RESB 10 ; reserve 10 bytes for input section .data list db 1,2,3,4,5 prompt db "Enter an integer: ", 0 prompt_len equ $ - prompt ; length of the prompt result_msg db "The sum is: ", 0 result_msg_len equ $ - result_msg buffer db 12 dup(0) ; buffer for input intArray dd 5 dup(0) arraySize db 0 sum dd 0 section .text global _start _start: mov ecx, 5 ; loop 5 times loop_prompt_handler: ; print the prompt to enter input mov eax, 4 ; sys_write mov ebx, 1 ; file descriptor 1 (stdout) mov ecx, prompt ; message to print mov edx, prompt_len ; number of bytes to read int 0x80 ; read the input mov eax, 3 ; sys_read mov ebx, 0 ; file descriptor 0 (stdin) mov ecx, input ; message to read mov edx, 10 ; number of bytes to read int 0x80 ; convert ASCII input to integer call str_to_int ; append to array mov ebx, [arraySize] ; load current size of the array mov edx, intArray ; load address of the array add edx, ebx ; point to the end of the array mov [edx], eax ; store the input number at the end of the array ; increment array size inc byte [arraySize] ; increment array size ; add the input number to the sum add dword [sum], eax loop loop_prompt_handler ; loop_prompt_handler label if ecx is not zero ; print the result mov eax, 4 ; sys_write mov ebx, 1 ; file descriptor 1 (stdout) mov ecx, result_msg ; message to print mov edx, result_msg_len ; number of bytes to read int 0x80 ; convert sum to string mov eax, [sum] mov ecx, buffer ; buffer containing the sum as a string call int_to_string ; print the sum mov eax, 4 ; sys_write mov ebx, 1 ; file descriptor 1 (stdout) mov edx, 12 ; length of the buffer int 0x80 ; exit mov eax, 1 ; sys_exit xor ebx, ebx ; exit code int 0x80 str_to_int: ; ecx: pointer to input string ; eax: result xor eax, eax ; clear eax xor edx, edx ; clear edx str_to_int_loop: movzx edx, byte [ecx] test dl, dl jz str_to_int_end sub dl, '0' imul eax, eax, 10 add eax, edx inc ecx jmp str_to_int_loop str_to_int_end: ret int_to_string: ; eax contains the string to convert ; ecx points to the buffer to store the string mov edi, ecx add edi, 11 mov byte [edi], 0 dec edi .convert_loop: xor edx, edx mov ebx, 10 div ebx add dl, '0' mov [edi], dl dec edi test eax, eax jnz .convert_loop inc edi mov ecx, edi ret
问题根源及修复方案
1. str_to_int函数参数未正确传入
你在注释中说明ecx是输入字符串指针,但调用str_to_int前,ecx被sys_write和sys_read修改为prompt和input后,没有显式把input地址重新加载到ecx,导致函数读取错误内存地址,触发段错误。
修复:调用str_to_int前添加地址传递代码:
; convert ASCII input to integer mov ecx, input ; 将输入缓冲区地址传入ecx call str_to_int
2. 数组偏移计算错误
intArray是dd类型(每个元素占4字节),但你用单字节类型的arraySize直接偏移数组地址,每次只移动1字节而非4字节,导致数组元素越界覆盖,触发内存访问错误。
修复:
- 将
arraySize改为双字类型:; 修改.data段的定义 arraySize dd 0 - 计算数组偏移时按4字节步长计算:
; append to array mov ebx, [arraySize] ; 加载当前元素个数 mov edx, intArray ; 数组基地址 lea edx, [edx + ebx*4] ; 计算第ebx个元素的地址(每个元素4字节) mov [edx], eax ; 存储转换后的整数
3. 未处理输入中的换行符
用户输入后按回车,sys_read会将换行符(0x0A)读入缓冲区,str_to_int会把它当成非数字字符处理,导致转换逻辑异常。
修复:在str_to_int循环中判断并终止换行符的处理:
str_to_int_loop: movzx edx, byte [ecx] test dl, dl jz str_to_int_end cmp dl, 0x0A ; 判断是否为换行符 jz str_to_int_end sub dl, '0' ; 后续代码不变
4. 打印总和时的长度错误
打印总和时直接使用固定长度12,但int_to_string返回的ecx是字符串起始地址,需要计算实际长度才能正确打印。
修复:打印前计算字符串长度:
; print the sum mov eax, 4 ; sys_write mov ebx, 1 ; file descriptor 1 (stdout) ; ecx已为字符串起始地址 mov edx, buffer + 12 ; 缓冲区末尾地址 sub edx, ecx ; 计算字符串实际长度 int 0x80
内容的提问来源于stack exchange,提问作者Harrylever
相关产品推荐
相关产品推荐

