You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

修复说明

  1. 字符串处理:读取后将换行符替换为0,确保字符串终止符正确,避免匹配错误
  2. 输入输出:添加了输入字符串的打印逻辑,符合预期输出格式
  3. 匹配逻辑:优化匹配流程,匹配成功后从下一个字符继续搜索,避免无限循环
  4. 索引打印:新增print_number辅助函数,支持多位数索引的ASCII转换,并打印完整提示文本

内容的提问来源于stack exchange,提问作者Faith Nnakwe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 18:04:50