2013-04-24 80 views
2

我正在參加一個彙編課程,並且我已經獲得了大部分程序寫出來,我只是無法替換該單詞並顯示新的字符串。問題要求提供一個句子,一個詞找到,並用一個詞來代替它。程序掃描字符串,替換單詞的任何實例,並向您顯示新字符串。
例如:「天空是藍的。」 單詞尋找:「天空」 單詞來代替它:「海洋」 新字符串:「海洋是藍色的。」在彙編中,我想搜索一個字符串,替換一個單詞,並顯示新的字符串

這是我到目前爲止有:

.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%確定我的「發現」代碼塊將會成爲問題所在。任何幫助深表感謝。

+0

您可以把寄存器暫時以'XCHG EDI, esi';或者你可以選擇一個完全不同的寄存器分配。沒有任何規定,例如使用'ecx'作爲計數器(除非您需要使用rep xxxx指令或循環)。 – 2013-04-24 10:41:44

+0

有很多方法來解決這個問題,有些很快,有些很簡單。在字符串中插入字符串既不是,循環中區分大小寫的比較速度也很慢。在任何語言中都可以在彙編程序中編寫優雅的解決方案。想想什麼可以更簡單或更快。在這種情況下,可能將單詞拆分爲字符串數組,輕鬆進行比較,並在完成時進行快速簡單的連接?另一種方法是將標記字節放入匹配字符中,並在加入時略過這些字符。彙編程序可以重新創建更好的車輪。 ;) – 2013-04-24 11:21:03

+0

我根本不知道x86,但是如果strlen(search)!= strlen(replace),看起來好像不插入/刪除字符。此外,你需要跳過strlen(搜索)字符,而不是隻有1個字符,當發現(EAX)。 (例如:用'xxx'代替'xx')。你仍然應該得到一些輸出,輸出是什麼?你是否單步執行代碼並觀察寄存器值? – 2013-04-24 11:38:25

回答

2

在處理x86彙編中的字符串時,必須快速掌握rep指令。如果沒有,你可能會在你的第一個程序完成之前消失。

a。在裝配的字符串操作非常不錯的介紹可以發現here(或here),但你真的需要這裏有如下的:

+0

您的第二個鏈接對解釋上述說明非常有幫助。我意識到我從一個錯誤的角度來看待它。我的程序仍然存在問題,但到目前爲止,您提供的幫助最多。謝謝。 – Seff 2013-04-24 20:37:31

相關問題