Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
String 程序集:用另一个字符串替换子字符串_String_Assembly_Replace_Substring - Fatal编程技术网

String 程序集:用另一个字符串替换子字符串

String 程序集:用另一个字符串替换子字符串,string,assembly,replace,substring,String,Assembly,Replace,Substring,您好,我是汇编新手,有一个练习要求我在原始字符串中查找子字符串,如果找到,则用另一个给定的字符串替换它,但仅对发现的奇数出现(1,3,5…)有一些问题。即 原始字符串:“abc世界定义世界” 要查找的字符串:“世界” 字符串替换:“cat” 输出:“acb cat def world” 此外,这些应该适用于所有类型的输入。即使像在本例中,“世界”比“猫”长,我也需要完全替换“世界”(“catld”是错误的)。 谁能帮帮我?!我不知道怎么处理。 这是我目前的代码,我仍然没有考虑这些奇怪的情况,

您好,我是汇编新手,有一个练习要求我在原始字符串中查找子字符串,如果找到,则用另一个给定的字符串替换它,但仅对发现的奇数出现(1,3,5…)有一些问题。即

  • 原始字符串:“abc世界定义世界”
  • 要查找的字符串:“世界”
  • 字符串替换:“cat”
  • 输出:“acb cat def world”
此外,这些应该适用于所有类型的输入。即使像在本例中,“世界”比“猫”长,我也需要完全替换“世界”(“catld”是错误的)。 谁能帮帮我?!我不知道怎么处理。 这是我目前的代码,我仍然没有考虑这些奇怪的情况,我只是想让它正常工作:

#include <stdio.h>

void main() {

    //Input
    char stringa[1024] ="This string is a string\n";
    char str1[] ="string";  
    char str2[] ="cat"; 

    //Output
    char result[1024];

    __asm {

        XOR EAX, EAX
        CLD
        LEA ESI, str1
        LEA EDI, stringa
Ciclo:  MOV AL, [ESI]
        REPNZ SCASB
        DEC EDI
        PUSH EDI
        PUSH ESI
        MOV ECX, 7
        REPE CMPSB
        CMP ECX, 0
        POP ESI
        JZ Sost
        JMP Ciclo

Sost:   LEA ESI, str2
        POP EDI
        MOV ECX, 7
        REP MOVSB
    }

    printf("New string: %s\n",result);
}
#包括
void main(){
//输入
char stringa[1024]=“此字符串是一个字符串\n”;
字符str1[]=“字符串”;
字符str2[]=“cat”;
//输出
字符结果[1024];
__asm{
异或EAX,EAX
CLD
LEA ESI,str1
李艾迪,斯特林加
Ciclo:MOV AL[ESI]
REPNZ SCASB
十二月电子数据交换
推式电子数据交换
推动ESI
MOV ECX,7
重复CMPSB
CMP-ECX,0
波普ESI
JZ Sost
JMP-Ciclo
Sost:LEA ESI,str2
流行电子数据交换
MOV ECX,7
代表MOVSB
}
printf(“新字符串:%s\n”,结果);
}

我的想法是这样的: 输入:原始字符串、要查找的子字符串、要替换的子字符串、输出字符串

  • 将EDI设置为原始字符串指向的第一个字节
  • 将ESI设置为要查找的子字符串指向的第一个字节
  • 移动到第一个子字符串字节
  • 读取原始字符串,直到与要查找的给定子字符串(SCASB)的第一个字符不同
  • 虽然不同,但将每个字符复制到输出字符串中
  • 当/如果它们匹配,则将ECX设置为子字符串长度
  • 从第一个匹配点开始,比较原始字符串和子字符串
  • 检查ECX
  • 若ECX为零,我有一个事件,所以转到检查点
  • 转到第4点
  • 检查点:a)增量发生计数器 b) 检查柜台。 c) 如果是奇数,请更换。 d) 转到第4点

    替换:a)将ECX设置为替换字符串长度 b) 复制输出字符串中的替换字符串 c) 转到第4点


    它看起来怎么样?

    我的想法是这样的: 输入:原始字符串、要查找的子字符串、要替换的子字符串、输出字符串

  • 将EDI设置为原始字符串指向的第一个字节
  • 将ESI设置为要查找的子字符串指向的第一个字节
  • 移动到第一个子字符串字节
  • 读取原始字符串,直到与要查找的给定子字符串(SCASB)的第一个字符不同
  • 虽然不同,但将每个字符复制到输出字符串中
  • 当/如果它们匹配,则将ECX设置为子字符串长度
  • 从第一个匹配点开始,比较原始字符串和子字符串
  • 检查ECX
  • 若ECX为零,我有一个事件,所以转到检查点
  • 转到第4点
  • 检查点:a)增量发生计数器 b) 检查柜台。 c) 如果是奇数,请更换。 d) 转到第4点

    替换:a)将ECX设置为替换字符串长度 b) 复制输出字符串中的替换字符串 c) 转到第4点


    它看起来是什么样子?

    下一个代码完成这项工作:它查找并用另一个字符串替换所有(非奇数)出现的字符串,并将结果字符串保留在另一个变量中,在编译器EMU8086中对其进行测试(我的VS不工作),代码后的解释:

    .model small
    .stack 100h
    .data
    original db 'abc world def world xyz',0
    find     db 'world',0
    subst    db 'cat',0
    result   db 100 dup(0)
    i        dw ?             ;INDEX FOR "ORIGINAL".
    j        dw ?             ;INDEX FOR "RESULT".
    .code
       mov  ax, @data
       mov  ds, ax
       mov  i, offset original ;"I" POINTS TO "ORIGINAL".
       mov  j, offset result   ;"J" POINTS TO "RESULT".
    ;SEARCH VARIABLE "FIND" AT CURRENT POSITION ("I").
       mov  si, i
       lea  di, find
    search:                        
       mov  al, [di]        ;CURRENT CHAR OF VARIABLE "FIND".
    ;CHECK IF END OF "FIND".
       cmp  al, 0           ;IF CURRENT CHAR OF "FIND" IS LAST ONE...
       je   match           ;... VARIABLE "FIND" WAS FOUND.
    ;CHECK IF END OF "ORIGINAL".
       cmp  [si], 0
       je   finale
    ;CONTINUE.   
       cmp  [si], al        ;CMP ORIGINAL[SI],FIND[DI].
       jne  mismatch        ;CHARS ARE DIFFERENT.
       inc  si              ;NEXT CHAR OF "ORIGINAL".
       inc  di              ;NEXT CHAR OF "FIND".
       jmp  search          ;REPEAT (COMPARE NEXT CHAR).
    match:
    ;WHEN "FIND" IS FOUND, "SUBST" REPLACE IT IN "RESULT".
       mov  i, si           ;SKIP "FIND" IN "ORIGINAL", BUT...
       dec  i               ;...SKIPPED ON CHAR FORWARD (SO DECREASE).
       lea  di, subst       ;STRING TO REPLACE "FIND".
    replace:
       mov  al, [di]        ;CURRENT CHAR OF VARIABLE "SUBST".
    ;CHECK IF END OF "SUBST".
       cmp  al, 0           ;IF CURRENT CHAR OF "FIND" IS LAST ONE...
       je   next
    ;CONTINUE.
       mov  si, j           ;CURRENT POSITION IN "RESULT".
       mov  [si], al        ;COPY CHAR INTO "RESULT[ J ]".
       inc  j               ;NEXT POSITION IN "RESULT".
       inc  di              ;NEXT POSITION IN "SUBST".
       jmp  replace
    mismatch:    
    ;APPEND CURRENT CHAR (AL) INTO "RESULT".
       mov  si, i           ;CURRENT POSITION IN "ORIGINAL".
       mov  di, j           ;CURRENT POSITION IN "RESULT".
       mov  al, [si]
       mov  [di], al
       inc  j               ;"I" IS ALSO INCREMENTED 4 LINES BELOW.
    ;NEXT CHAR IN "ORIGINAL".
    next:
       lea  di, find        ;SEARCH AGAIN VARIABLE "FIND".
       inc  i               ;NEXT CHAR IN "ORIGINAL".
    ;CHECK IF END OF "ORIGINAL".
       mov  si, i
       cmp  [si], 0
       jne  search          ;REPEAT (SEARCH "FIND" AGAIN).
    ;END OF WHOLE PROCESS.
    finale:
       mov  ax, 4c00h
       int  21h
    
    结果是:

    original = `abc world def world xyz`
    find     = `world`
    subst    = `cat`
    result   = `abc cat def cat xyz`
    
    注意,在代码中,所有字符串(数据段中的变量)都使用
    0
    作为结束分隔符。这一点非常重要,因为这是处理任意大小字符串的关键,而不是硬编码大小的字符串

    现在算法是:

  • 它在“原件”中的每个字符上循环
  • 当访问“original”中的每个字符时,将搜索字符串“find”
  • 如果未找到“find”,则“original”中的当前字符将附加在“result”中
  • 如果找到“find”,则字符串“subst”将附加在“result”中,“i”(指向“original”)的指针)跳转到搜索循环结束的位置(减1),以跳过我们要替换的字符串。“j”(指向“result”的指针)从不跳过,它总是增加1
  • 要使其适用于奇数出现,请添加另一个数值变量作为计数器,该计数器在标签
    匹配:
    下增加,如果变量在标签
    搜索:
    之后不是奇数,请使其跳转到标签
    下一步:

    编辑:现在是Visual Studio 2013版本(在“C++Win32控制台应用程序”上测试):

    编辑#2:以前的代码,变量
    i
    j
    分别被
    ebx
    ecx
    替换(我留下了注释中的“i”和“j”部分,以便您可以看到我在哪里进行了替换):


    下一个代码执行此任务:它查找并用另一个字符串替换所有(非奇数)出现的字符串,并将结果字符串保留在另一个变量中,在编译器EMU8086中对其进行测试(my VS不工作),代码后解释:

    .model small
    .stack 100h
    .data
    original db 'abc world def world xyz',0
    find     db 'world',0
    subst    db 'cat',0
    result   db 100 dup(0)
    i        dw ?             ;INDEX FOR "ORIGINAL".
    j        dw ?             ;INDEX FOR "RESULT".
    .code
       mov  ax, @data
       mov  ds, ax
       mov  i, offset original ;"I" POINTS TO "ORIGINAL".
       mov  j, offset result   ;"J" POINTS TO "RESULT".
    ;SEARCH VARIABLE "FIND" AT CURRENT POSITION ("I").
       mov  si, i
       lea  di, find
    search:                        
       mov  al, [di]        ;CURRENT CHAR OF VARIABLE "FIND".
    ;CHECK IF END OF "FIND".
       cmp  al, 0           ;IF CURRENT CHAR OF "FIND" IS LAST ONE...
       je   match           ;... VARIABLE "FIND" WAS FOUND.
    ;CHECK IF END OF "ORIGINAL".
       cmp  [si], 0
       je   finale
    ;CONTINUE.   
       cmp  [si], al        ;CMP ORIGINAL[SI],FIND[DI].
       jne  mismatch        ;CHARS ARE DIFFERENT.
       inc  si              ;NEXT CHAR OF "ORIGINAL".
       inc  di              ;NEXT CHAR OF "FIND".
       jmp  search          ;REPEAT (COMPARE NEXT CHAR).
    match:
    ;WHEN "FIND" IS FOUND, "SUBST" REPLACE IT IN "RESULT".
       mov  i, si           ;SKIP "FIND" IN "ORIGINAL", BUT...
       dec  i               ;...SKIPPED ON CHAR FORWARD (SO DECREASE).
       lea  di, subst       ;STRING TO REPLACE "FIND".
    replace:
       mov  al, [di]        ;CURRENT CHAR OF VARIABLE "SUBST".
    ;CHECK IF END OF "SUBST".
       cmp  al, 0           ;IF CURRENT CHAR OF "FIND" IS LAST ONE...
       je   next
    ;CONTINUE.
       mov  si, j           ;CURRENT POSITION IN "RESULT".
       mov  [si], al        ;COPY CHAR INTO "RESULT[ J ]".
       inc  j               ;NEXT POSITION IN "RESULT".
       inc  di              ;NEXT POSITION IN "SUBST".
       jmp  replace
    mismatch:    
    ;APPEND CURRENT CHAR (AL) INTO "RESULT".
       mov  si, i           ;CURRENT POSITION IN "ORIGINAL".
       mov  di, j           ;CURRENT POSITION IN "RESULT".
       mov  al, [si]
       mov  [di], al
       inc  j               ;"I" IS ALSO INCREMENTED 4 LINES BELOW.
    ;NEXT CHAR IN "ORIGINAL".
    next:
       lea  di, find        ;SEARCH AGAIN VARIABLE "FIND".
       inc  i               ;NEXT CHAR IN "ORIGINAL".
    ;CHECK IF END OF "ORIGINAL".
       mov  si, i
       cmp  [si], 0
       jne  search          ;REPEAT (SEARCH "FIND" AGAIN).
    ;END OF WHOLE PROCESS.
    finale:
       mov  ax, 4c00h
       int  21h
    
    结果是:

    original = `abc world def world xyz`
    find     = `world`
    subst    = `cat`
    result   = `abc cat def cat xyz`
    
    注意,在代码中,所有字符串(数据段中的变量)都使用
    0
    作为结束分隔符。这一点非常重要,因为这是处理任意大小字符串的关键,而不是硬编码大小的字符串

    现在算法是:

  • 它在“原件”中的每个字符上循环
  • 当访问“original”中的每个字符时,将搜索字符串“find”
  • 如果未找到“find”,则“original”中的当前字符将附加在“result”中
  • 如果找到“find”,字符串“subst”将附加在“result”中,“i”(指向“original”的指针)将跳过搜索循环结束的位置(减去1),以便跳过我们要替换的字符串。“j”(指向“re”的指针
        __asm {
                    XOR EAX, EAX
                    XOR EBX, EBX
                    XOR EDX, EDX
                    CLD
                    LEA EDI, str1
                    LEA ESI, stringa
    
                    Cicle : 
                            MOV AL, [ESI]
        //CHECK IF STRING ENDED
                            CMP AL, 0
                            JZ End
        //CHECK THE CHAR
                            SCASB
        //IF THEY DON'T MATCH GO TO COPY CHAR
                            JNZ Append
        //OTHERWISE CHECK IF FROM HERE STRINGS ARE EQUAL
                            MOV ECX, LENGTH str1
                            DEC EDI
                            REPE CMPSB
                            CMP ECX, 0
        //IF YES GO TO CHECK IF IT'S AN ODD OCCURRENCE
                            JZ Checkpoint
        //IF NOT GET BACK ESI AND EDI...
                            NEG ECX
                            ADD ECX, LENGTH str1
                            SUB EDI, ECX
                            SUB ESI, ECX
        //..AND COPY THE SINGLE CHAR
                            MOV risultato[EBX], AL
                            INC EBX
                            INC ESI
                            JMP Cicle
    
        //COPY CHAR WHEN STRINGS DONT'MATCH    
                    Append :
                            INC ESI
                            DEC EDI
                            MOV risultato[EBX], AL
                            INC EBX
                            JMP Cicle
    
        //CHEK IF ODD/EVEN OCCURRENCE               
                    Checkpoint :
                            INC EDX
                            TEST EDX, 00000001h
        //IF ODD GO TO REPLACE ALL SUBSTRING
                            JNZ Replacement
        //OTHERWISE GET BACK ESI/EDI AND COPY THE SAME SUBSTRING TO RESULT
                            SUB EDI, LENGTH str1
                            SUB ESI, LENGTH str1
                            PUSH EDI
                            LEA EDI, risultato[EBX]
                            MOV ECX, LENGTH str1
                            REP MOVSB
        //UPDATE RESULT INDEX COUNTER
                            ADD EBX, LENGTH str1 - 1
        //GET BACK EDI POINTER
                            POP EDI
                            DEC ESI
                            JMP Cicle
    
        //REPLACEMENT OF THE SUBSTRING                  
                    Replacement :
        //GET BACK EDI AT FIRST CHAR AND STORE ESI/EDI FOR NEXT LOOP
                            SUB EDI, LENGTH str1
                            PUSH ESI
                            PUSH EDI
        //SET A POINTER TO THE NEW STRING AND COPY IT TO RESULT
                            LEA ESI, str2
                            LEA EDI, risultato[EBX]
                            MOV ECX, LENGTH str2
                            REP MOVSB
        //UPDATE RESULT COUNTER AND GET BACK EDI/ESI TO PREVIOUS POSITIONS TO CONTINUE
                            ADD EBX, LENGTH str2 - 1
                            POP EDI
                            POP ESI
                            DEC ESI
                            JMP Cicle
    
                    End :
                            MOV risultato[EBX], 0
    }
    
            XOR ECX, ECX
            XOR EAX, EAX
            XOR EBX, EBX
            XOR EDX, EDX
            LEA ESI, result
            PUSH ESI                //store result into stack
            LEA ESI, original       //esi points to original
            LEA EDI, find           //edi points to find
    
            Search :
                MOV AL, [EDI]
                    CMP AL, 0           //chek if the end of find
                    JE Match            //if yes, we have an occurrence
                    CMP[ESI], 0         //check if end of original
                    JE Mismatch         //if yes, coopy last char going to Mismatch
                    CMP[ESI], al        //check if char match
                    JNE Mismatch        //if yes go to Mismatch
                    INC ESI             //else repeat Search to check if next char match
                    INC EDI
                    INC ECX             //chars counter
                    JMP Search
    
            Match :
                INC EBX                 //occurrences counter
                    TEST EBX, 00000001h
                    JZ Mismatch         //if even go to Mismatch else continue...
                    LEA EDI, str2       //else point to new string to replace
                    MOV EDX, ESI        //copy the current original pointer
                    POP ESI             //store it also into the stack
    
            Replacement :
                MOV AL, [EDI]           //copy new string char by char
                    CMP AL, 0
                    JE SetRegister      //if end of new string, get back the pointers
                    MOV[ESI], AL        //else continue...
                    INC ESI
                    INC EDI
                    JMP Replacement
    
            Mismatch :
                POP EDI                 //edi points to result
                    SUB ESI, ECX        //set esi to the char it was pointing before Search or Match
                    INC ECX             //shows how many chars we need to replace
                    REP MOVSB           //ready to copy chars from original to result
                    PUSH EDI
                    CMP[ESI], 0         //check if original has ended
                    JZ Fine
                    DEC ESI
                    XOR ECX, ECX        //set to zero the chars counter
                    JMP Next            //go to Next char
    
            SetRegister :
                PUSH ESI                //after replacement set registers right positions
                    MOV ESI, EDX
                    DEC ESI
                    XOR ECX, ECX
    
            Next :
                LEA EDI, find           //ready to find next char
                    INC ESI
                    CMP[ESI], 0
                    JNE Search
    
            Fine :
                POP EDI
                    MOV[EDI], 0         //close the result string