String 程序集:用另一个字符串替换子字符串
您好,我是汇编新手,有一个练习要求我在原始字符串中查找子字符串,如果找到,则用另一个给定的字符串替换它,但仅对发现的奇数出现(1,3,5…)有一些问题。即String 程序集:用另一个字符串替换子字符串,string,assembly,replace,substring,String,Assembly,Replace,Substring,您好,我是汇编新手,有一个练习要求我在原始字符串中查找子字符串,如果找到,则用另一个给定的字符串替换它,但仅对发现的奇数出现(1,3,5…)有一些问题。即 原始字符串:“abc世界定义世界” 要查找的字符串:“世界” 字符串替换:“cat” 输出:“acb cat def world” 此外,这些应该适用于所有类型的输入。即使像在本例中,“世界”比“猫”长,我也需要完全替换“世界”(“catld”是错误的)。 谁能帮帮我?!我不知道怎么处理。 这是我目前的代码,我仍然没有考虑这些奇怪的情况,
- 原始字符串:“abc世界定义世界”
- 要查找的字符串:“世界”
- 字符串替换:“cat”
- 输出:“acb cat def world”
#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”,结果);
}
我的想法是这样的:
输入:原始字符串、要查找的子字符串、要替换的子字符串、输出字符串
它看起来怎么样?我的想法是这样的: 输入:原始字符串、要查找的子字符串、要替换的子字符串、输出字符串
它看起来是什么样子?下一个代码完成这项工作:它查找并用另一个字符串替换所有(非奇数)出现的字符串,并将结果字符串保留在另一个变量中,在编译器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
作为结束分隔符。这一点非常重要,因为这是处理任意大小字符串的关键,而不是硬编码大小的字符串
现在算法是:
匹配:
下增加,如果变量在标签搜索:
之后不是奇数,请使其跳转到标签下一步:
编辑:现在是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
作为结束分隔符。这一点非常重要,因为这是处理任意大小字符串的关键,而不是硬编码大小的字符串
现在算法是:
__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