下一个代码完成这项工作:它找到并用另一个字符串替换所有(不奇怪)出现的字符串,并将结果字符串留在另一个变量中,在编译器 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”(指向“结果”的指针)从不跳过,它总是加一。
要使其适用于奇数事件,请在标签match: 下添加另一个数值变量作为计数器,如果该变量在标签search: 之后不是奇数,则使其跳转到标签next:。
编辑:现在是 Visual Studio 2013 版本(在“C++ Win32 控制台应用程序”上测试):
#include "stdafx.h"
#include "conio.h"
int _tmain(int argc, _TCHAR* argv[])
{ //Input
char original[1024] = "abc world def world xyz\n";
char find[] = "world";
char subst[] = "cat";
//Output
char result[1024] = { 0 };
int i;
int j;
_asm { lea esi, original
mov i, esi // "I" POINTS TO "ORIGINAL".
lea esi, result
mov j, esi // "J" POINTS TO "RESULT".
// SEARCH VARIABLE "FIND" AT CURRENT POSITION ("I").
mov esi, i
lea edi, find
search:
mov al, [edi] // 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 [esi], 0
je finale
// CONTINUE.
cmp [esi], al // CMP ORIGINAL[SI],FIND[DI].
jne mismatch // CHARS ARE DIFFERENT.
inc esi // NEXT CHAR OF "ORIGINAL".
inc edi // NEXT CHAR OF "FIND".
jmp search // REPEAT (COMPARE NEXT CHAR).
match:
// WHEN "FIND" IS FOUND, "SUBST" REPLACE IT IN "RESULT".
mov i, esi // SKIP "FIND" IN "ORIGINAL", BUT...
dec i // ...SKIPPED ON CHAR FORWARD (SO DECREASE).
lea edi, subst // STRING TO REPLACE "FIND".
replace:
mov al, [edi] // 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 esi, j // CURRENT POSITION IN "RESULT".
mov [esi], al // COPY CHAR INTO "RESULT[ J ]".
inc j // NEXT POSITION IN "RESULT".
inc edi // NEXT POSITION IN "SUBST".
jmp replace
mismatch:
// APPEND CURRENT CHAR (AL) INTO "RESULT".
mov esi, i // CURRENT POSITION IN "ORIGINAL".
mov edi, j // CURRENT POSITION IN "RESULT".
mov al, [esi]
mov [edi], al
inc j // "I" IS ALSO INCREMENTED 4 LINES BELOW.
// NEXT CHAR IN "ORIGINAL".
next:
lea edi, find // SEARCH AGAIN VARIABLE "FIND".
inc i // NEXT CHAR IN "ORIGINAL".
// CHECK IF END OF "ORIGINAL".
mov esi, i
cmp [esi], 0
jne search // REPEAT (SEARCH "FIND" AGAIN).
// END OF WHOLE PROCESS.
finale:
}
printf("New string: %s", result );
_getch();
return 0;
}
编辑#2:以前的代码用变量i 和j 分别替换为ebx 和ecx(我留下了cmets 说“I”和“J”的部分,所以你可以看到我在哪里做了替换):
#include "stdafx.h"
#include "conio.h"
int _tmain(int argc, _TCHAR* argv[])
{ //Input
char original[1024] = "abc world def world xyz\n";
char find[] = "world";
char subst[] = "cat";
//Output
char result[1024] = { 0 };
_asm { lea esi, original
mov ebx, esi // "I" POINTS TO "ORIGINAL".
lea esi, result
mov ecx, esi // "J" POINTS TO "RESULT".
// SEARCH VARIABLE "FIND" AT CURRENT POSITION ("I").
mov esi, ebx
lea edi, find
search:
mov al, [edi] // 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 [esi], 0
je finale
// CONTINUE.
cmp [esi], al // CMP ORIGINAL[SI],FIND[DI].
jne mismatch // CHARS ARE DIFFERENT.
inc esi // NEXT CHAR OF "ORIGINAL".
inc edi // NEXT CHAR OF "FIND".
jmp search // REPEAT (COMPARE NEXT CHAR).
match:
// WHEN "FIND" IS FOUND, "SUBST" REPLACE IT IN "RESULT".
mov ebx, esi // SKIP "FIND" IN "ORIGINAL", BUT...
dec ebx // ...SKIPPED ON CHAR FORWARD (SO DECREASE).
lea edi, subst // STRING TO REPLACE "FIND".
replace:
mov al, [edi] // 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 esi, ecx // CURRENT POSITION IN "RESULT".
mov [esi], al // COPY CHAR INTO "RESULT[ J ]".
inc ecx // NEXT POSITION IN "RESULT".
inc edi // NEXT POSITION IN "SUBST".
jmp replace
mismatch:
// APPEND CURRENT CHAR (AL) INTO "RESULT".
mov esi, ebx // CURRENT POSITION IN "ORIGINAL".
mov edi, ecx // CURRENT POSITION IN "RESULT".
mov al, [esi]
mov [edi], al
inc ecx // "I" IS ALSO INCREMENTED 4 LINES BELOW.
// NEXT CHAR IN "ORIGINAL".
next:
lea edi, find // SEARCH AGAIN VARIABLE "FIND".
inc ebx // NEXT CHAR IN "ORIGINAL".
// CHECK IF END OF "ORIGINAL".
mov esi, ebx
cmp [esi], 0
jne search // REPEAT (SEARCH "FIND" AGAIN).
// END OF WHOLE PROCESS.
finale:
}
printf("New string: %s", result );
_getch();
return 0;
}