在TASM程序集中计算文件大小

时间:2017-10-30 20:31:48

标签: assembly x86 dos tasm

我的作业听起来有点像这样

  

在Intel x86程序集中编写程序,该程序从控制台(用户输入)获取参数:第一个参数 - 文件大小(以字节为单位),其他参数 - 必须分析的目录的完整路径。程序查找给定目录中大于指定大小的文件,然后将其访问属性更改为只读。此外,程序将这些文件的编号列表输出到单独的文件

(抱歉翻译不好,英语是我的第二语言。)

所以我已经编写了一些代码来显示需要时的帮助信息;创建结果文件;将给定大小存储在缓冲区中;浏览目录并分析文件;

.model small ; kiek skirti atminties programai

.stack 100h ; steko dydis

.data ; data segmento pradžia

    message                 db      "Nr.", 10 dup (' '), "Pavadinimas", 10 dup (' '), "Dydis (B)", 3 dup (' '), '$' ; pirma žinutė rezultatų faile
    resultFile_n            db      "rez.txt", 0 ; rezultatų failo pavadinimas                                                          
    help                    db      "Pirmasis parametras - failo dydis baitais,", 10, 13, "visi kiti - pilni keliai iki norimu nagrineti direktoriju.$" ; pagalbos pranešimas
    file                    dw      ?   ; failo handleris
    ; DTA start
    DTA                     db      255 dup( 0 )    ; data transfer address
    fileName                db      250 dup ( 0 )   ; failo pavadinimas
    fileName_n              dw      0
    fileSize                db      10 dup ( '0' )  ; failo dydis
    fileSize_n              dw      0
    ; DTA end
    sizeHigh                dw      0
    sizeLow                 dw      0
    remainderHigh           dw      0
    remainderLow            dw      0
    newLine                 db      0Dh, 0Ah
    space                   db      ' '
    ; parametrų bufferis start
    buffer_asize            db      0h  ; bufferio dydis
    buffer                  db      255 dup ( ? ); buferis, kuriam saugosiu parametrų eilutę
    ; parametrų bufferis end
    ; vartotojo įvesto dydžio bufferis start
    sizeBuffer_asize        db      0h  ; actual size
    sizeBuffer              db      255 dup ( ? )
    ; vartotojo įvesto dydžio bufferis end
    ; directory buffer start
    directory_asize         dw      0h
    directoryBuffer         db      254 dup ( ? ), 0
    ; directory buffer end


.code

start:

    mov ax, @data               ; perkeliam iš data į registrą ax
    mov ds, ax                  ; perkeliam iš ax į data segmentą

    xor ch, ch                  ; nunulinam ch, nes naudosim cl
    mov cl, es:[80h]            ; programos paleidimo parametrų simbolių skaičius, kuris rašomas ES 80h baite
    cmp cx, 0                   ; jei vartotojas nedavė jokių parametrų
    je Exit1                    ; nereikia nieko tikrinti, programą užbaigam
    mov bx, 81h                 ; programos paleidimo parametrai rašomi ES nuo 81h baito, įmetam į bazinį registrą, kad galėtumėm adresuoti

    FindHelp:                   ; ieškom pagalbos simbolio

        cmp es:[bx], '?/'       ; lyginam pagalbos pranešimo simbolį su simboliu esančiu BX poslinkiu ES
        ; atmintyje jaunesnysis baitas saugomas pirmiau,
        ; todėl pirmasis baitas įrašomas į bl, antras į bh
        ; dėl to /? virsta į ?/

        je SendHelp             ; reikia spausdinti pagalbos pranešimą
        inc bx                  ; didinam bx ( poslinkį )
        loop FindHelp           ; jei dar nepatikrinom visų parametrų - tikrinam toliau

        jmp AllParamsChecked    ; jei visi parametrai patikrinti, tai nereikia spausdinti pagalbos pranešimo

    SendHelp:                   ; spausdinam pagalbos pranešimą

        mov ah, 9
        lea dx, help
        int 21h
        jmp Exit1

    AllParamsChecked:                   ; tęsiam programą, jei nereikia spausdinti pagalbos pranešimo

        xor cx, cx              ; nustatom failo atributą į 0 ( read-only )
        mov ah, 3Ch             ; failo sukūrimo komanda
        lea dx, resultFile_n    ; failo vardas
        int 21h                 ; kuriam rezultatų failą
        mov file, ax            ; išsisaugom handlerį velėsniam darbui su failu

        mov ah, 40h             ; spausdinam pirmą eilutę rezultatų faile
        mov bx, file
        mov cx, 46d             ; kiek baitų įrašyti
        lea dx, message
        int 21h

        mov bx, file            ; pereinam į naują eilutę
        mov cx, 2d
        mov ah, 40h
        lea dx, newLine
        int 21h

        mov ah, 1Ah             ; nurodau DTA 
        lea dx, DTA
        int 21h

        mov cl, es:[80h]        ; programos paleidimo parametrų simbolių skaičius paimamas iš ES 80h baito
        dec cl                  
        mov buffer_asize, cl    ; išsaugom buferio dydį kintamąjame
        cmp cl, 0h
        jz Exit1                ; jei nėra parametrų, baigiam programą

        mov si, 0               ; poslinkį nustatom į 0
        xor ch, ch              ; nunulinam ch, nes ciklo skaitliukui naudosim CX ( mums reikia tik CL reikšmės )

        ReadLoop:   ; skaitom visus vartotojo įvestus parametrus ( failo dydį ir direktorijas )

            mov al, es:[82h + si]   ; skaitom parametrus iš ES segmento poslinkiu SI, į AL
            mov [ buffer + si ], al ; iš AL perkeliam į bufferį tolesniam darbui
            inc si                  ; didinam poslinkį

        loop ReadLoop


        ; Exit'as nes vienu jumpu nenušoksim
        jmp Next1

        Exit1:
            jmp Finish

        Next1:
        ; End Exit'as

        xor bx, bx
        xor dx, dx
        mov dl, buffer_asize

        SaveSize:   ; išsaugom vartotojo įvestą dydį bufferyje lyginimui

            cmp bx, dx
            jae Exit2                   ; jei nėra direktorijų baigiam programą
            cmp [ buffer + bx ], ' '    ; dydis parametrų eilutėje įrašytas iki pirmo tarpo
            je NextDirectory

            mov cl, [ buffer + bx ]
            mov [ sizeBuffer + bx ], cl
            inc bx                  ; pereinam į kitą simbolį
            inc sizeBuffer_asize    ; didinam dydžio ilgį
            jmp SaveSize

        NextDirectory:

            xor dx, dx
            mov dl, buffer_asize
            cmp bx, dx
            jae Exit2

            xor si, si  ; jei imam kitą direktoriją, tai pradedam bufferį pildyt iš naujo
            inc bx  ; praleidžiam tarpą

            Directory:  ; aprodojam direktoriją

                xor dx, dx
                mov dl, buffer_asize
                cmp dx, bx
                je EndReading

                cmp [ buffer + bx ], ' '    ; jei ne tarpas, reiškias vis dar skaitom simbolius tos pačios direktorijos
                je EndReading

                mov al, [ buffer + bx ]
                mov [ directoryBuffer + si ], al

                inc si
                inc bx

                jmp Directory

            EndReading:

                ; prie direktorijos galo pridedu *.*, kad ieškotų visų failų toje direktorijoje
                mov [ directoryBuffer + si ], '*'
                inc si
                mov [ directoryBuffer + si ], '.'
                inc si
                mov [ directoryBuffer + si ], '*'
                inc si
                mov [ directoryBuffer + si ], 0

                mov directory_asize, si

                ; atranda pirmą failą nurodytoje direktorijoje
                mov ah, 4Eh ; find first ASCIZ
                xor cx, cx 
                lea dx, directoryBuffer
                int 21h
                jc Exit2    ; jei klaida

                jmp ProcessFile

            ; Exit'as2
            jmp Next2
            Exit2:
                jmp Finish
            Next2:
            ;End exit'as 2

            NextFile: ; ieško kitų failų nurodytoje direktorijoje

                mov ah, 4Fh
                xor cx, cx
                lea dx, directoryBuffer
                int 21h
                jc NextDirectory    ; jei nėra failų

        ProcessFile:
            ; failo dydis saugomas dviejuose žodžiuose = keturiuose baituose = 32 bit
            ; 32 bit skaičių reikia konvertuoti į ASCII simbolį
            mov dh, [ DTA + 1Dh ]
            mov dl, [ DTA + 1Ch ]
            mov sizeHigh, dx

            mov ah, [ DTA + 1Bh ]
            mov al, [ DTA + 1Ah ]
            mov sizeLow, ax

            xor si, si

            GetFileSize: ;//


            jmp Next3

            NextFile1:
                jmp NextFile

            Next3:


            CompareSize: ;//


            WriteToFile:    

                mov fileSize_n, si
                xor si, si
                xor ax, ax
                mov di, 1Eh

                GetFileName: 

                    cmp [ DTA + di ], 0
                    je Write

                    mov al, [ DTA + di ]
                    mov [ fileName + si ], al

                    inc di
                    inc si

                    jmp GetFileName

            Write:

                mov fileName_n, si

                push bx

                mov ah, 43h ; padarom read only
                mov al, 01h
                mov cx, 01h
                lea dx, fileName
                int 21h 

                ; call SpaceLoop

                mov ah, 40h 
                mov bx, file
                mov cx, fileName_n
                lea dx, fileName
                int 21h

                ; call SpaceLoop

                ; mov ah, 40h
                ; mov bx, file
                ; mov cx, 4d
                ; lea dx, sizeLow
                ; int 21h

                mov bx, file            ; pereinam į naują eilutę
                mov cx, 2d
                mov ah, 40h
                lea dx, newLine
                int 21h

                pop bx

                jmp NextFile1

    Finish:         ; užbaigiam programą

        mov ah, 3Eh     ; uždarom failą
        mov bx, file
        int 21h

        mov ah, 4Ch     ; returning to dos, interrupto komandos numeris.
        mov al, 0       ; no errors
        int 21h         ; dos interrupt

    SpaceLoop proc

        mov cx, 13

        loop1:

            push cx

            mov bx, file
            mov cx, 1d
            mov ah, 40h
            lea dx, space
            int 21h

            pop cx

        loop loop1
        ret

    SpaceLoop endp

end start  

(评论是我的母语,所以请忽略它们)

这就是问题所在:我不知道如何计算和存储文件大小及其名称在不同的缓冲区中。

应该怎么做?

欢迎提出其他意见和建议。

0 个答案:

没有答案