assembly 搜索字符串中出现的所有子字符串

brvekthn  于 2022-11-13  发布在  其他
关注(0)|答案(1)|浏览(171)

此程序必须搜索字符串1中字符串2的所有匹配项。
它与我试过的所有字符串都很好用,除了与
s1="Ciao Cia Cio Ociao ciao Ocio CiCiao CieCiaCiu CiAo eeCCia"
s2="Cia"
在这种情况下,正确的结果将是:0 5 31 39 54
而是打印0 5 39
我不明白为什么,操作看起来和
s1="Sette scettici sceicchi sciocchi con la sciatica a Shanghai"
s2="icchi"
程序可以正常工作。
我找不到错误!
代码:

#include <stdio.h>

void main()
{
    #define MAX_LEN 100

        // Input
    char s1[] = "Ciao Cia Cio Ociao ciao Ocio CiCiao CieCiaCiu CiAo eeCCia";
    unsigned int lengthS1 = sizeof(s1) - 1;
    char s2[] = "Cia";
    unsigned int lengthS2 = sizeof(s2) - 1;
    // Output
    unsigned int positions[MAX_LEN];
    unsigned int positionsLen;

    // Blocco assembler
    __asm
    {
        MOV ECX, 0
        MOV EAX, 0
        DEC lenghtS1
        DEC lengthS2
        MOV EBX, lengthS1
        CMP EBX, 0
        JZ fine
        MOV positionsLen, 0
        XOR EBX, EBX
        XOR EDX, EDX



    uno: CMP ECX, lengthS1
    JG fine
    CMP EAX, lengthS2
    JNG restart
    XOR EAX, EAX

    restart : MOV BH, s1[ECX]
    CMP BH, s2[EAX]
    JE due
    JNE tre

    due : XOR EBX, EBX
    CMP EAX, 0
    JNE duedue
    MOV positions[EDX * 4], ECX
    INC ECX
    INC EAX
    JMP uno

    duedue : CMP EAX, lengthS2
    JNE duetre
    INC ECX
    INC EDX
    INC positionsLen
    XOR EAX, EAX
    JMP uno

    duetre : INC EAX
    INC ECX
    JMP uno

    tre : XOR EBX, EBX
    XOR EAX, EAX
    INC ECX
    JMP uno



fine:
    }

    // Stampa su video
    {
        unsigned int i;
        for (i = 0; i < positionsLen; i++)
            printf("Sottostringa in posizione=%d\n", positions[i]);
    }
}

请帮帮我。

q3aa0525

q3aa05251#

编程越复杂,你的方法就应该越系统化和深思熟虑。如果你已经在x86汇编程序中工作了十年,你就可以跳过我下面列出的几个步骤。但是,特别是如果你是一个初学者,建议你不要指望自己可以在没有安全网的情况下自信地进行汇编。
下面的代码只是一个最好的猜测(我没有编译、运行或调试C代码)。它就在那里,给予了想法。

  • 制定实施计划

因此,您将有2个嵌套循环,比较字符,然后收集匹配项。

  • 在低级C中实施“组装”,这已经类似于最终产品。

C语言本身几乎是一种汇编语言...

  • 自己编写测试,调试和分析你的“伪汇编”C版本。
  • 按装配线逐步翻译C线,将C线“提升”为注解。

这是我第一次尝试这样做--最初的c版本,它可能会工作,也可能不会工作。但它仍然更快,更容易写(考虑到汇编代码)。更容易调试和单步调试。一旦工作,是时候“翻译”了。

#include <stdint.h>
#include <stddef.h>
#include <string.h>

size_t substring_positions(const char *s, const char* sub_string, size_t* positions, size_t positions_capacity) {
  size_t positions_index = 0;
  size_t i = 0;
  size_t j = 0;
  size_t i_max = strlen(s) - strlen(sub_string);
  size_t j_max = strlen(sub_string) - 1;

 loop0:
  if (i > i_max)
    goto end;
  j = 0;
 loop1:
  if (j == j_max)
    goto match;
  if (s[i+j] == sub_string[j])
    goto go_on;
  i++;
  goto loop0;
 go_on:
  j++;
  goto loop1;
 match:
  positions[positions_index] = i;
  positions_index++;
  if (positions_index < positions_capacity)
    goto loop0;
  goto end;
    
 end:
  return positions_index;
}

正如你所看到的,我没有为这个函数使用“高级语言特性”(C语言有这样的特性吗?!:)。现在,你可以开始“汇编”了。如果RAX应该保存你的i变量,你可以用XOR RAX,RAX替换size_t i = 0;。等等。
使用这种方法,其他人甚至有机会阅读汇编代码,并通过注解(以前的c代码)说明指令的意图。

相关问题