我正在參加一個彙編課程,並且我已經獲得了大部分程序寫出來,我只是無法替換該單詞並顯示新的字符串。問題要求提供一個句子,一個詞找到,並用一個詞來代替它。程序掃描字符串,替換單詞的任何實例,並向您顯示新字符串。
例如:「天空是藍的。」 單詞尋找:「天空」 單詞來代替它:「海洋」 新字符串:「海洋是藍色的。」在彙編中,我想搜索一個字符串,替換一個單詞,並顯示新的字符串
這是我到目前爲止有:
.586
.MODEL FLAT
INCLUDE io.h ; header file for input/output
.STACK 4096
.DATA
prompt1 BYTE "String to Search: ", 0
prompt2 BYTE "Word to Search For: ", 0
prompt3 BYTE "Word to replace with: ", 0
target BYTE 80 DUP (?)
key BYTE 80 DUP (?)
strSub BYTE 80 DUP (?)
trgtLength DWORD ?
keyLength DWORD ?
lastPosn DWORD ?
strSubLen DWORD ?
resultLbl BYTE "The new sentence is: ", 0
.CODE
_MainProc PROC
input prompt1, target, 80 ;input target string
lea eax, target ;address of target
push eax ;parameter
call strlen ;strlen(target)
add esp, 4 ;remove parameter
mov trgtLength, eax ;save length of target
input prompt2, key, 80 ;input key string
lea eax, key ;address of key
push eax ;parameter
call strlen ;strlen(key)
add esp, 4 ;remove parameter
mov keyLength, eax ;save length of key
input prompt3, strSub, 80 ;input word to search for
lea eax, strSub ;address of key
push eax ;parameter
call strlen ;strlen(strSub)
add esp, 4 ;remove parameter
mov strSubLen, eax ;save length of key
mov eax, trgtLength
sub eax, keyLength
inc eax ;trgtLength - keyLength +1
mov lastPosn, eax
cld ;Left to Right comparison
mov eax, 1 ;starting position
whilePosn:
cmp eax, lastPosn ;position <= last_posn?
jnle endWhilePosn ;exit if past last position
lea esi, target ;address of target string
add esi, eax ;add position
dec esi ;address of position to check
lea edi, key ;address of key
mov ecx, keyLength ;number of position to check
repe cmpsb ;check
jz found ;exit of success
inc eax ;increment position
jmp whilePosn ;repeat
endWhilePosn:
output resultLbl, [esi] ;display new sentence
jmp quit
found:
sub edi, keyLength
mov ecx, strSubLen
lea esi, strSub
cld
rep movsb
inc eax
jmp whilePosn
quit:
mov eax, 0 ; exit with return code 0
ret
_MainProc ENDP
strlen PROC
push ebp ;establish stack frame
mov ebp, esp
push ebx ;save EBX
sub eax, eax ;length := 0
mov ebx, [ebp+8] ;address of string
whileChar:
cmp BYTE PTR [ebx], 0 ;null byte?
je endWhileChar ;exit if so
inc eax ;increment length
inc ebx ;point at next character
jmp whileChar ;repeat
endWhileChar:
pop ebx ;restore registers
pop ebp
ret
strlen ENDP
END
代碼的工作就發現,我想改用這個詞,但實際切換的話是騙我。這本書說目標字符串應該在EDI中,替換的單詞應該在ESI中,但是他們給出的代碼在ESI中有目標字符串,在EDI中有字符替換(就像我在這裏)。
這本書在解釋「rep」和「movs」指令方面做得非常糟糕,所以我90%確定我的「發現」代碼塊將會成爲問題所在。任何幫助深表感謝。
您可以把寄存器暫時以'XCHG EDI, esi';或者你可以選擇一個完全不同的寄存器分配。沒有任何規定,例如使用'ecx'作爲計數器(除非您需要使用rep xxxx指令或循環)。 – 2013-04-24 10:41:44
有很多方法來解決這個問題,有些很快,有些很簡單。在字符串中插入字符串既不是,循環中區分大小寫的比較速度也很慢。在任何語言中都可以在彙編程序中編寫優雅的解決方案。想想什麼可以更簡單或更快。在這種情況下,可能將單詞拆分爲字符串數組,輕鬆進行比較,並在完成時進行快速簡單的連接?另一種方法是將標記字節放入匹配字符中,並在加入時略過這些字符。彙編程序可以重新創建更好的車輪。 ;) – 2013-04-24 11:21:03
我根本不知道x86,但是如果strlen(search)!= strlen(replace),看起來好像不插入/刪除字符。此外,你需要跳過strlen(搜索)字符,而不是隻有1個字符,當發現(EAX)。 (例如:用'xxx'代替'xx')。你仍然應該得到一些輸出,輸出是什麼?你是否單步執行代碼並觀察寄存器值? – 2013-04-24 11:38:25