x86汇编程序问题:无法输出搜索字符串在输入串中的位置
x86汇编字符串匹配问题修复
需求:编写x86汇编程序,输出搜索字符串在输入字符串中的所有出现位置。现有代码仅能读取两个字符串,无法完成匹配及输出操作。
原代码
section .data ; Define the maximum length of the search string MAX_SEARCH_LENGTH equ 1000 section .bss ; Define variables SEARCH_KEY resb MAX_SEARCH_LENGTH INPUT resb MAX_SEARCH_LENGTH index_counter resd 1 index_counter1 resd 1 temp resd 1 section .text global main main: ; Read the search string mov eax, 0 ; sys_read syscall number mov edi, 0 ; file descriptor 0 (stdin) mov esi, SEARCH_KEY mov edx, MAX_SEARCH_LENGTH syscall ; Check if search string contains a newline mov ecx, SEARCH_KEY mov ebx, 0 ; counter check_newline_loop: cmp byte [ecx + ebx], 10 ; newline character je found_newline inc ebx cmp ebx, MAX_SEARCH_LENGTH jl check_newline_loop ; If no newline found, print error message and exit mov eax, 1 ; sys_write syscall number mov edi, 1 ; file descriptor 1 (stdout) mov esi, error_message mov edx, error_message_length syscall jmp exit found_newline: ; Read the input data mov eax, 0 ; sys_read syscall number mov edi, 0 ; file descriptor 0 (stdin) mov esi, INPUT mov edx, MAX_SEARCH_LENGTH syscall ; Set up index_counter for comparison xor eax, eax mov [index_counter], eax compare_first: ; Compare characters xor eax, eax mov eax, [index_counter] mov bl, byte [INPUT + eax] cmp bl, 0 je exit cmp bl, byte [SEARCH_KEY] je set_index inc dword [index_counter] jmp compare_first set_index: xor eax, eax mov eax, 0 mov [index_counter1], eax jmp next_characters next_characters: mov eax, [index_counter1] add eax, 1 mov [index_counter1], eax mov bl, byte [SEARCH_KEY + eax] cmp bl, 0 je print_index xor eax, eax mov eax, [index_counter] add eax, [index_counter1] mov [temp], eax mov bl, byte [INPUT + eax] cmp bl, 0 je exit mov ecx, [index_counter1] mov eax, [temp] mov bl, byte [SEARCH_KEY + ecx] cmp bl, byte [INPUT + eax] je next_characters jmp increase_counter increase_counter: xor eax, eax mov eax, [index_counter] inc dword [index_counter] jmp compare_first print_index: ; Print the index mov eax, 1 ; sys_write syscall number mov edi, 1 ; file descriptor 1 (stdout) mov esi, [temp] add esi, 48 ; convert index to ASCII add esi, 0x30 mov edx, 1 syscall jmp next_characters exit: ; Exit the program mov eax, 60 ; sys_exit syscall number xor edi, edi ; exit code 0 syscall section .data error_message db "Error: Search string not found.", 0xA error_message_length equ $ - error_message searchString db "Enter search string: ", 10, 0 inputString db "Enter input string: ", 10, 0
输入示例
o hello world.
预期输出
o hello world. found at position: 4 found at position: 7
问题分析与修复代码
原代码存在以下核心问题:
- 未将搜索字符串末尾的换行符替换为字符串终止符
0,导致匹配逻辑错误 - 索引打印逻辑错误:直接操作内存地址而非字符值,缺少提示文本,且未处理匹配完成后的继续搜索
- 未打印输入的两个字符串,不符合预期输出要求
- 匹配完成后未重置索引,导致无限循环
修复后的完整代码:
section .data MAX_SEARCH_LENGTH equ 1000 error_message db "Error: Search string too long.", 0xA error_message_length equ $ - error_message found_msg db "found at position: " found_msg_len equ $ - found_msg newline db 0xA section .bss SEARCH_KEY resb MAX_SEARCH_LENGTH INPUT resb MAX_SEARCH_LENGTH index_counter resd 1 ; 当前输入字符串的遍历索引 match_counter resd 1 ; 当前匹配的搜索字符串字符索引 temp_buffer resb 10 ; 用于转换数字为ASCII的缓冲区 section .text global main main: ; 读取搜索字符串 mov eax, 0 mov edi, 0 mov esi, SEARCH_KEY mov edx, MAX_SEARCH_LENGTH syscall ; 替换搜索字符串的换行符为0,并检查长度 mov ecx, SEARCH_KEY mov ebx, 0 search_newline_loop: cmp byte [ecx + ebx], 10 je search_newline_found inc ebx cmp ebx, MAX_SEARCH_LENGTH - 1 ; 留一个字节给终止符 jl search_newline_loop ; 未找到换行,输出错误退出 mov eax, 1 mov edi, 1 mov esi, error_message mov edx, error_message_length syscall jmp exit search_newline_found: mov byte [ecx + ebx], 0 ; 替换换行为字符串终止符 ; 打印搜索字符串 mov eax, 1 mov edi, 1 mov esi, SEARCH_KEY mov edx, ebx ; 长度是换行前的字符数 syscall ; 打印换行 mov eax, 1 mov edi, 1 mov esi, newline mov edx, 1 syscall ; 读取输入字符串 mov eax, 0 mov edi, 0 mov esi, INPUT mov edx, MAX_SEARCH_LENGTH syscall ; 替换输入字符串的换行符为0 mov ecx, INPUT mov ebx, 0 input_newline_loop: cmp byte [ecx + ebx], 10 je input_newline_found cmp byte [ecx + ebx], 0 ; 如果read读到EOF,直接终止 je input_newline_found inc ebx cmp ebx, MAX_SEARCH_LENGTH - 1 jl input_newline_loop input_newline_found: mov byte [ecx + ebx], 0 ; 打印输入字符串 mov eax, 1 mov edi, 1 mov esi, INPUT mov edx, ebx syscall ; 打印换行 mov eax, 1 mov edi, 1 mov esi, newline mov edx, 1 syscall ; 初始化遍历索引 xor eax, eax mov [index_counter], eax compare_start: ; 取当前输入字符 mov eax, [index_counter] mov bl, byte [INPUT + eax] cmp bl, 0 je exit ; 输入字符串遍历完成,退出 ; 对比搜索字符串首字符 cmp bl, byte [SEARCH_KEY] je start_match ; 不匹配,索引+1继续 inc dword [index_counter] jmp compare_start start_match: ; 初始化匹配计数器 xor eax, eax mov [match_counter], eax match_loop: mov eax, [match_counter] ; 取搜索字符串当前字符 mov cl, byte [SEARCH_KEY + eax] cmp cl, 0 je match_found ; 搜索字符串全部匹配完成 ; 取输入字符串对应位置字符 mov ebx, [index_counter] add ebx, eax mov dl, byte [INPUT + ebx] cmp dl, 0 je exit ; 输入提前结束,无匹配 ; 对比字符 cmp cl, dl jne match_failed ; 匹配失败,回到主循环 ; 匹配成功,继续下一个字符 inc dword [match_counter] jmp match_loop match_found: ; 打印匹配提示 mov eax, 1 mov edi, 1 mov esi, found_msg mov edx, found_msg_len syscall ; 将index_counter转换为ASCII并打印 mov eax, [index_counter] call print_number ; 打印换行 mov eax, 1 mov edi, 1 mov esi, newline mov edx, 1 syscall ; 从当前位置的下一个字符继续搜索 inc dword [index_counter] jmp compare_start match_failed: ; 匹配失败,索引+1继续 inc dword [index_counter] jmp compare_start ; 辅助函数:将EAX中的数字打印为十进制ASCII print_number: mov ebx, temp_buffer + 9 ; 从缓冲区末尾开始 mov byte [ebx], 0 ; 终止符 mov ecx, 10 number_loop: xor edx, edx div ecx add dl, 0x30 ; 转换为ASCII dec ebx mov [ebx], dl cmp eax, 0 jne number_loop ; 打印缓冲区中的字符串 mov eax, 1 mov edi, 1 mov esi, ebx mov edx, temp_buffer + 9 - ebx syscall ret exit: mov eax, 60 xor edi, edi syscall
修复说明
- 字符串处理:读取后将换行符替换为
0,确保字符串终止符正确,避免匹配错误 - 输入输出:添加了输入字符串的打印逻辑,符合预期输出格式
- 匹配逻辑:优化匹配流程,匹配成功后从下一个字符继续搜索,避免无限循环
- 索引打印:新增
print_number辅助函数,支持多位数索引的ASCII转换,并打印完整提示文本
内容的提问来源于stack exchange,提问作者Faith Nnakwe
相关产品推荐
相关产品推荐

