更改字符串(文件扩展名)

Changing a String (filename extension)

我是新来的。这是交易: 我需要读取一个文件名,然后验证它是否以“.IN”结尾,如果不是,我需要添加它才能打开文件。之后,我需要创建一个文件,文件名相同,但以“.OUT”结尾,替换“.IN”

GetFileName proc    near
    lea     bx,MsgEnterFilename
    call    printf_s ;It prints the string above
    mov     ah,0ah
    lea     dx,FileNameBuffer
    mov     byte ptr FileNameBuffer,100
    int     21h
    lea     si,FileNameBuffer+2
    lea     di,FileName
    mov     cl,FileNameBuffer+1
    mov     ch,0
    mov     ax,ds
    mov     es,ax
    rep     movsb
    mov     byte ptr es:[di],0 ;Puts a '[=10=]' at the end
    ret
GetFileName endp

fileNameInfo proc near ;Puts ".IN" and ".OUT"
    lea     si, FileName
    lea     di, FileNameCopy
    mov     cx, MAXSTRING ; MAXSTRING is set to 256, yeah, I am copying beyond the string end
    rep movsb 

    ; Search for ".IN"
    mov     si, 0

start_filename_length:                
    mov     al, FileNameCopy[si]  

    cmp     al, 0
    je      end_filename_length

    inc     FileNameLength
    inc     FileNameLengthAux

    add     si, 1
    jmp     start_filename_length
end_filename_length:

    sub     FileNameLengthAux, 2 ; To begin the test in the last 3 bytes (".IN")
    mov     si, word ptr FileNameLengthAux
    cmp     FileNameCopy[si], "."
    je      test_i
    jmp     no_extension
test_i:
    inc     si
    mov     si, word ptr FileNameLengthAux
    cmp     FileNameCopy[si], "I"
    je      test_n
    cmp     FileNameCopy[si], "i"
    je      test_n
    jmp     no_extension
test_n:
    inc     si  ; last byte
    mov     si, word ptr FileNameLengthAux
    cmp     FileNameCopy[si], "N" 
    je      correct_extension
    cmp     FileNameCopy[si], "n"
    je      correct_extension
    ;jmp    no_extension

no_extensao: ;wrong extension counts as no extension
    inc     FileNameLengthAux       ;goes to '[=10=]' position
    mov     si, word ptr FileNameLengthAux
    mov     FileNameCopy[si], "."
    inc     si
    mov     FileNameCopy[si], "O"
    inc     si
    mov     FileNameCopy[si], "U"
    inc     si
    mov     FileNameCopy[si], "T"
    inc     si
    mov     FileNameCopy[si], 0 ;End the string

    lea     si, FileNameCopy
    lea     di, FileNameOut
    mov     cx, MAXSTRING ; copy 256 bytes
rep movsb

    jmp     return_filename_info

correct_extension: ;copyies till the "."
    mov     bl, FileNameLengthAux
    mov     FileNameLength, bl
    sub     FileNameLength, 2
    lea     si, FileNameCopy
    lea     di, FileNameOut
    mov     ch, 0
    mov     cl, FileNameLengthAux
rep movsb
    mov     si, word ptr FileNameLengthAux ; it is on "." position
    inc     si
    mov     FileNameOut[si], "O"
    inc     si
    mov     FileNameOut[si], "U"
    inc     si
    mov     FileNameOut[si], "T"
    inc     si
    mov     FileNameOut[si], 0 ;End the string
    ;jmp    return_filename_info

return_filename_info:

    ret
fileNameInfo endp

感谢帮助=D

sub     FileNameLengthAux, 2 ; To begin the test in the last 3 bytes (".IN")

这就是著名的差一错!您需要减去 3.
用一个例子来验证这一点。如果文件名是 "A.IN",长度将为 4,您将要开始寻找“.”。偏移量 SI=1 处的字符。算一下:4 - 3 = 1.

test_i:
    inc     si
    mov     si, word ptr FileNameLengthAux

为什么要破坏 SI 的(正确的)增量值?

test_i:
    inc     si
    mov     si, word ptr FileNameLengthAux

同样的问题。

mov     bl, FileNameLengthAux
mov     FileNameLength, bl
sub     FileNameLength, 2

您如何期望它给出正确的最终 FileNameLength
FileNameLengthAux 已经小于原来的长度(你减去 2),这里你让它更小(再减去 2)!
所需要的只是返回一个长度,该长度正好比您开始时的长度大 1


如果您的程序没有找到扩展名 (".IN"),您根本不会更新 FileNameLength。只需添加 4,因为这是附加的“.OUT”的长度。

调用在主程序中PS。: 对不起,评论是葡萄牙语

;Constants
AscUpi              equ     "I"
AscLowi             equ     "i"
AscUpn              equ     "N"
AscLown             equ     "n"
AscUpo              equ     "O"
AscLowo             equ     "o"
AscUpu              equ     "U"
AscLowu             equ     "u"
AscUpt              equ     "T"
AscLowt             equ     "t"
AscDot              equ     "."

call    GetFileName
call    GetFileNameLength
call    VerifyFileName
call    GenFileNameOut

VerifyFileName proc near
    mov     dx, FileNameLength
    mov     FileNameLengthAux, dx ; SI considera FileName[0] como sendo a 1a posição, como vetores em C
    sub     FileNameLengthAux, 3 ;FileNameLength - 3 -> posição do . em ".IN"
    mov     si, FileNameLengthAux ;"."
    ;mov    dx, "."
    cmp     FileNameIn[si], AscDot
    je      testa_i
    jmp     no_extension
testa_i:
    inc     si  ;FileNameLength - 2 -> posição do I em ".IN" ;"i" ou "I"
    ;mov    dx, "I"
    cmp     FileNameIn[si], AscUpi
    je      testa_n
    ;mov    dx, "i"
    cmp     FileNameIn[si], AscLowi
    je      testa_n
    jmp     no_extension
testa_n:
    inc     si ;FileNameLength - 1 -> posição do N em ".IN" ;"n" ou "N"
    ;mov    dx, "N"
    cmp     FileNameIn[si], AscUpn
    je      right_extension
    ;mov    dx, "n"
    cmp     FileNameIn[si], AscLown
    je      right_extension
    jmp     no_extension
no_extension: ;Inclui extensao errada, caso seja entrado 123.abc, será transformado em 123.abc.in (.in são os últimos 3 caracteres)
    mov     dx, FileNameLength
    mov     FileNameLengthAux, dx
    sub     FileNameLengthAux, 1
    mov     si, FileNameLengthAux
    inc     si
    ;mov    dx, "."
    mov     byte ptr FileNameIn[si], AscDot
    inc     FileNameLength ; Ajusta o FileNameLength somando os 3 caracteres que acabaram de ser adicionados
    inc     si
    ;mov    dx, "I"
    mov     byte ptr FileNameIn[si], AscUpi ; No PDF está especificado '.IN'
    inc     FileNameLength ; Ajusta o FileNameLength somando os 3 caracteres que acabaram de ser adicionados
    inc     si
    ;mov    dx, "N"
    mov     byte ptr FileNameIn[si], AscUpn
    inc     FileNameLength ; Ajusta o FileNameLength somando os 3 caracteres que acabaram de ser adicionados
    inc     si
    mov     FileNameIn[si], 0 ; Fecha a String do nome de arquivo
    ;jmp    right_extension
right_extension:
    ;FILENAMEIN ESTA CORRETO
    ret
VerifyFileName endp
GenFileNameOut proc near
    ;O nome do arquivo de entrada está correto agora, e o tamanho foi atualizado caso tenha sido necessário
    ;Copiar o FileNameIn para FileNameOut e fazer os ajustes (.IN -> .OUT)

    mov     cx, FileNameLength
    lea     si, FileNameIn
    lea     di, FileNameOut
    rep     movsb ; Cópia de strings

    ;agora FileNameOut = FileNameIn

    mov     ax, FileNameLength
    mov     FileNameLengthAux, ax
    sub     FileNameLengthAux, 2 ; Vai para a posição do "I" em ".IN"
    mov     si, FileNameLengthAux
    mov     byte ptr FileNameOut[si], "O" ; Subtitui o 'I' por 'O'
    inc     si
    mov     byte ptr FileNameOut[si], "U" ; Subtitui o 'N' por 'U'
    inc     si
    mov     byte ptr FileNameOut[si], "T" ; Subtitui o 0 por 'T'
    inc     si
    mov     byte ptr FileNameOut[si], 0   ; Subtitui o 0 por 0

    ;FILENAMEOUT ESTA CORRETO
    ;call   NewLine
    ;lea    bx, FileNameOut
    ;call   printf_s

    ;FileNameOut está pronto
    ;jmp    return_filename_out
return_filename_out:
    ret
GenFileNameOut endp
GetFileNameLength proc near
    mov     si, 0 ;primeira posicao da string
inicio_filename_length: 
    mov     al, FileNameIn[si]
    cmp     al, 0
    je      fim_filename_length
    inc     FileNameLength      
    inc     FileNameLengthAux   ;Cópia de FileNameLength
    inc     si
    ;add    si, 1
    jmp     inicio_filename_length
fim_filename_length:
    ret
GetFileNameLength endp