assembly 如何在汇编中比较两个字符串并在txt文件中替换一个?

nwo49xxi  于 2023-11-19  发布在  其他
关注(0)|答案(1)|浏览(102)

我需要写一个汇编程序,它会在数据txt文件中搜索一个字符串,并将其替换为第二个字符串。在结果txt文件中,我需要接收相同的txt文件,但字符串必须被替换。在我写的程序中,一切正常,直到TextManipulations部分,我不明白我应该做什么。

.MODEL small
.STACK 256
.DATA
    help db "Hello,", 10, 13, "provide arguments like in the example: program.exe data.txt abcd EFG res.txt", 10, 13, "$"
    FileProblem db "Provided file wasn't found.", 10, 13, "Provide arguments like in the example: program.exe data.txt abcd EFG res.txt", 10, 13, "$"
    input db 255 dup(0)
    inputFD dw, ?               
    string1 db 255 dup(0)
    string2 db 255 dup(0)
    output db 255 dup(0)
    outputFD dw, ?              
    buffer db 50000 dup(?)
    tempBuf db 255 dup(?)       
.CODE
Start:
    mov ax, @data
    mov ds, ax

    xor cx, cx
    xor ah, ah
    mov cl, [es:0080h]
    cmp cx, 4
    jbe Helpmsg
    jne SkipHelp

SkipHelp:

    xor di, di
    mov bx, 82h
    mov si, offset input
    call SaveArgument
    mov si, offset string1
    call SaveArgument
    mov si, offset string2
    call SaveArgument
    mov si, offset output
    call SaveArgument

    xor ax, ax
    mov ah, 3Dh
    mov al, 00
    mov dx, offset input
    int 21h
    jc MissingFile
    mov inputFD, ax

    mov ah, 3Fh
    mov bx, inputFD
    mov cx, 200
    mov dx, offset buffer
    int 21h

    mov ah, 3Ch
    mov cx, 0
    mov dx, offset output
    int 21h
    mov outputFD, ax
    
    call TextManipulations
    
    mov ah, 3Eh
    mov bx, outputFD
    int 21h

Final:
    mov ah, 4Ch
    int 21h

Helpmsg:
    mov ah, 09h
    mov dx, offset help
    int 21h
    JMP Final

MissingFile:
    mov ah, 09h
    mov dx, offset FileProblem
    int 21h
    jmp Final

SaveArgument PROC
Begin:
    mov dx, [es:bx]
    inc bx
    cmp dl, 20h
    je StopSpace
    cmp dl, 13
    je StopEnter
    mov byte ptr [si], dl
    inc si
    jmp Begin
StopSpace:
    inc di
    ret
StopEnter:
    cmp di, 3
    jb Helpme
    ret
Helpme:
    mov ah, 09h
    mov dx, offset help
    int 21h
    mov ah, 4Ch
    int 21h
    ret
SaveArgument ENDP

TextManipulations PROC
    mov si, offset buffer
    mov di, offset string1
    xor cx, cx
    push cx

Read:
    mov ah, 3Fh
    mov bx, inputFD
    mov cx, 1
    mov dx, si
    int 21h    

    cmp byte ptr [si], 0
    je Return
    mov al, byte ptr [si]
    mov ah, byte ptr [di]
    cmp al, ah
    je CheckForString
    mov al, 0
    mov ah, 40h
    mov bx, outputFD
    mov dx, offset tempBuf
    mov cx, 1
    int 21h
    mov cx, 1
    mov dx, si
    int 21h
    inc si
    mov di, offset string1
    pop cx
    xor cx, cx
    push cx

    jmp Read

CheckForString:
    pop cx
    inc cx
    inc di
    cmp byte ptr [di], 0
    je PrintString
    push di
    mov di, offset tempBuf
    mov byte ptr [di], al
    pop di
    inc si
    push cx
    jmp Read

PrintString:
    pop cx
    mov ah, 40h
    mov bx, outputFD
    mov cx, 1                           
    mov dx, offset string2
    int 21h
    inc si
    xor cx, cx
    push cx
    jmp Read

Return:
    ret

TextManipulations ENDP

END Start

字符串
我已经尝试了很多不同的方法来比较和改变这些字符串,但是每次它是两个中的一个,它改变了字符串,但没有打印所有的符号或不完全工作。

ux6nzvsh

ux6nzvsh1#

更新:

好吧,我写了这个proc TextManipulations。我认为它是工作。正确的值是在缓冲区,但问题是这一部分:

Save_to_res_txt:        
    mov ah, 40h
    mov bx, outputFD
    mov cx, 9; filesize                           
    mov dx, offset buffer
    int 21h

字符串
filesize是从文件data.txt读取的字节数。字符串操作程序后,应使用ah = 40h, int 21h从缓冲区写入相同数量的字节到文件res.txt。编译器显示所有寄存器中的良好值,但在int 21 h后,res.txt 慡硡䙅G扸扢中出现随机字符。
如果程序写入超过9个字节,则在文件res.txt中存在随机字符。如果小于或等于9,则文件包含良好值(12个中的9个)。

如果我将输出从文件更改为控制台mov bx, 2程序显示正确的字符串。

我不知道该怎么做,所以我使用标准输出来显示最终结果。

第一个答案

我在调试器里检查过了。是的,问题出在TextManipulations里面。
例如data.txt包含以下字符aaaxabcdxbbb
buffer = aaaxabcdxbbbstring1 = abcd
第一次比较就OK了

mov al, byte ptr [si]               ; 61 | 61
    mov ah, byte ptr [di]               ; 61 | 62
    cmp al, ah


CheckForStringdi移动到string1中的下一个位置。字符保存到tmpBuffer,程序跳转到检查下一个字符。
现在我们有ab,所以这是不匹配的。
mov ah, 40htmpBufferres.txt写入1个字符(cx = 1)。
下一部分停止调试器,返回系统。

mov cx, 1
    mov dx, si
    int 21h


如果我把input改为abaxabcdxbbb,输出里面只有b。字符总是存储在tmpBuffer的同一个地方,因为di总是等于offset tempBuf

产品代码:

.MODEL small
.STACK 256
.DATA
    help db "Hello,", 10, 13, "provide arguments like in the example: program.exe data.txt abcd EFG res.txt", 10, 13, "$"
    FileProblem db "Provided file wasn't found.", 10, 13, "Provide arguments like in the example: program.exe data.txt abcd EFG res.txt", 10, 13, "$"
    input db 255 dup(0)
    inputFD dw ?               
    filesize dw 0                   
    string1 db 255 dup(0)
    string2 db 255 dup(0)
    output db 255 dup(0)
    outputFD dw ?              
    buffer db 512 dup(?)
    tempBuf db 255 dup(?) 
      
.CODE
Start:
    mov ax, @data
    mov ds, ax

    xor cx, cx
    xor ah, ah
    mov cl, [es:0080h]
    cmp cx, 4                           ; 4 parameters, 26 characters total, skip Helpmsg
    jbe Helpmsg
    jne SkipHelp

SkipHelp:

    xor di, di                          ; di = 0
    mov bx, 82h                         ; bx = parameter area(81h) + 1 (skip space)
    mov si, offset input                ; save argument in input / data.txt - input file ... offset 00c7
    call SaveArgument                   ; data.txt copied to ds:00c7
    mov si, offset string1              ; save argument in string1 / abcd ... offset 01ca
    call SaveArgument                   ; abcd copied to ds:01ca
    mov si, offset string2              ; save argument in string2 / EFG ... offset 02c9
    call SaveArgument                   ; EFG copied to ds:02c9
    mov si, offset output               ; save argument in output / res.txt - output file ... offset 03c8
    call SaveArgument                   ; res.txt copied to ds:03c8

    xor ax, ax                          
    mov ah, 3Dh                         ; open file
    mov al, 00                          ; read-only
    mov dx, offset input                ; data.txt
    int 21h                     
    jc MissingFile
    mov inputFD, ax                     ; data.txt handle

    mov ah, 3Fh                         ; read from data.txt
    mov bx, inputFD                     ; data.txt handle
    mov cx, 200                         ; read 200 bytes    
    mov dx, offset buffer               ; read here, ds:04c9
    int 21h                             ; return ax = 12 bytes read
                                        ; data.txt = aaaxabcdxbbb
    mov filesize, ax                    ; save file size, we use this later
    
    mov ah, 3Ch                         ; create / open file
    mov cx, 2                           ; read-only
    mov dx, offset output               ; file name "res.txt"
    int 21h
    mov outputFD, ax                    ; res.txt handle
    
    call TextManipulations              
    
    mov ah, 3Eh                         ; close file
    mov bx, outputFD
    int 21h

Final:
    mov ah, 4Ch                         ; bye
    int 21h

Helpmsg:
    mov ah, 09h
    mov dx, offset help
    int 21h
    JMP Final

MissingFile:
    mov ah, 09h
    mov dx, offset FileProblem
    int 21h
    jmp Final

SaveArgument PROC
Begin:
    mov dx, es:[bx]                     ; dx = character from parameter area            
    inc bx                              ; move to next character
    cmp dl, 20h                         ; space separates parameters
    je StopSpace
    cmp dl, 13                          ; we reached end of parameters area
    je StopEnter
    mov byte ptr [si], dl               ; insert character to [si]
    inc si                              ; next position in memory area pointed by si
    jmp Begin                           ; repeat
StopSpace:                              
    inc di                              ; increment number of parameters or count spaces between params ?
    ret                                 ; we are done here
StopEnter:
    cmp di, 3                           ; 3 spaces separates 4 params, if less we have error
    jb Helpme
    ret
Helpme:
    mov ah, 09h
    mov dx, offset help
    int 21h
    mov ah, 4Ch                         ; see You next time
    int 21h
    ret
SaveArgument ENDP

TextManipulations PROC
    mov si, offset buffer               ; buffer = aaaxabcdxbbb, 04c9
    mov di, offset string1              ; string1 = abcd, 01c6
    xor cx, cx                          ; matching letters counter
    mov dx, di                          ; save offset of the first character in string1 

    Read:   
        cmp byte ptr [si], 0            ; end of buffer ?
        je Return                       ; yes, no more characters in buffer, return
    
        Characters_cmp:
            mov al, byte ptr [si]       ; 61 | 61
            mov ah, byte ptr [di]       ; 61 | 62
            cmp al, ah
            je Characters_are_equal
    
        Reset_strings:                  ; characters are diffrent
            cmp dx,di                   ; if first letter in string1 is diffrent from letter in buffer
            jz next_in_buffer           ; take another letter from buffer to avoid infinity loop    
        
            mov di, offset string1      ; else just reset position in string1
            jmp Reset_counter
        
        next_in_buffer:
            inc si      

        Reset_counter:
            xor cx, cx                  ; reset counter
            jmp Characters_cmp

    Characters_are_equal:
        inc cx                          ; increase counter
        inc si                          ; next character in buffer
        inc di                          ; we want to check next character in string1
        cmp byte ptr [di], 0            ; we checked all characters ?
        je ReplaceString                ; yes, we found matching string

        jmp Read

    ReplaceString:
        sub si,cx                           ; move to start of the matching string
        mov bx, offset string2              ; copy this to buffer
        
        Copy_new_string:
            mov al,[bx]
            mov [si],al
            inc si
            inc bx
            loop Copy_new_string
    
    
        Save_to_res_txt:        
            mov ah, 40h
            mov bx, 2             ;[outputFD]
            mov cx, [filesize]    ; 9                           
            mov dx, offset buffer
            int 21h

    Return:
        ret
TextManipulations ENDP
END Start

相关问题