我的作业听起来有点像这样
在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
(评论是我的母语,所以请忽略它们)
这就是问题所在:我不知道如何计算和存储文件大小及其名称在不同的缓冲区中。
应该怎么做?
欢迎提出其他意见和建议。