1.显示指定目录下的文件清单,包括文件名、扩展名、文件大小(十进制数表示)、最后修改日期和时间等项内容(不显示属性为隐含的文件,各项内容之间以制表符的位置起始);
2.根据参数确定显示方式(W:紧凑显示,每个文件只显示文件的文件名及扩展名;P:显示文件的全部信息,对清单进行分页处理,满屏后暂停,并提示按任意键继续显示剩余的信息;无参数则当满屏后作滚屏处理);
这学期选修了汇编语言课程实践,实现了题目中的全部要求,肝project的时候临近考试了,只是用了几个晚上达到了最低纲领,实现的不是很优雅,代码中甚至有一定的冗余代码,仅供参考。
1 data segment
2 org 80h
3 psp dw 0ffh dup(?)
4 ddd db 'diretory:$'
5 head db 'name size type date time ',0dh,0ah,24h
6 space db ' ',24h
7 dir db 'xxx <dir> ',24h
8 fn db 200h dup(?)
9 dta db 128 dup(?)
10 msg db 'press any key to continue...',0dh,0ah,24h
11 newline db 0dh,0ah,24h
12 count db ?
13 show db 0
14 base_10 dw 10
15 used_32bits_high dw 0
16 used_32bits_low dw 0
17 var_32bits_high dw 0
18 var_32bits_low dw 0
19 quotidient_32bits_high dw 0
20 quotidient_32bits_low dw 0
21 negate_mask equ 0FFFFh
22 lowest_signed_32bits_high dw 8000h
23 lowest_signed_32bits_low dw 0000h
24 lowest_signed_32bits_string db '-2147483648$'
25 qhigh dw 0
26 rhigh dw 0
27 qlow dw 0
28 rlow dw 0
29 qhigh_redundant dw 0
30 rhigh_redundant dw 0
31 q_0 dw 0
32 qhigh0 equ 0h
33 rhigh0 equ 0h
34 qhigh1 equ 1999h
35 rhigh1 equ 6h
36 qhigh2 equ 3333h
37 rhigh2 equ 2h
38 qhigh3 equ 4CCCh
39 rhigh3 equ 8h
40 qhigh4 equ 6666h
41 rhigh4 equ 4h
42 qhigh5 equ 8000h
43 rhigh5 equ 0h
44 qhigh6 equ 9999h
45 rhigh6 equ 6h
46 qhigh7 equ 0B333h
47 rhigh7 equ 2h
48 qhigh8 equ 0CCCCh
49 rhigh8 equ 8h
50 qhigh9 equ 0E666h
51 rhigh9 equ 4h
52 filenum db 0
53 dirnum db 0
54 filespace db ' File(s) $'
55 dirspace db ' Dir(s) $'
56 bytes db ' Bytes.',0dh,0ah,24h
57 bytesfree db ' Bytes free.',0dh,0ah,24h
58 data ends
59
60 stack1 segment stack
61 dw 0ffh dup(0)
62 stack1 ends
63
64 main segment
65 assume cs:main,ds:data,ss:stack1
66 org 100h
67 cmdln equ byte ptr es:[82h] ;command line data
68
69 ;-------------------------------------------------------------------------------
70 p1 proc near
71 push ds
72 mov ax,data
73 mov ds,ax
74 pop psp
75 mov es,psp
76 mov ax,stack1
77 mov ss,ax
78 mov cl,byte ptr es:[80h]
79 cmp cl,0 ;command line?
80 jne l4 ;yes
81 no_dir:
82 mov ah,19h ;no
83 int 21h
84 add al,'a'
85 mov byte ptr[fn],al
86 mov word ptr[fn+1],5c3ah
87 mov ah,47h ;current directory but no driver,so have to
88 lea si,fn[3] ;use 19h to add myself
89 sub al,'a'
90 mov dl,al
91 int 21h
92
93 lea di,fn[3] ;to point di to the end of the diretory
94
95 l7:
96 mov al,[di]
97 cmp al,0
98 je l6
99 inc di
100 jmp l7
101
102 l4:
103 lea si,cmdln
104 lea di,fn
105 cld
106 xor ch,ch
107 dec cl
108 ;rep movsb
109
110 lea di,fn
111 lea bx,cmdln
112 lea bp,fn
113
114 repeat:
115
116 mov al,es:[bx]
117 mov ds:[bp],al
118 inc bx
119 inc bp
120 inc di
121 dec cl
122 jnz repeat
123
124 l6:
125 mov cl,[di-1] ;end by '\' ?
126 cmp cl,92 ;92-->'\'
127 je l8 ;yes
128 ;mov byte ptr[di],92 ;no
129 ;inc di
130
131 cmp byte ptr[di-1],'W'
132 jne notW
133 mov al,1
134 mov [show],al
135 notW:
136 cmp byte ptr[di-1],92 ;'\'
137 je l8
138 dec di
139 jz no_dir
140 jmp notW
141
142 l8:
143 mov word ptr[di],0a0dh ;end by $ for printing
144 mov byte ptr[di+2],24h
145 mov ah,09h ;print "directory:*:\*\*\"
146 ;lea dx,ddd
147 mov dx,offset ddd
148 int 21h
149 mov ah,09h
150 lea dx,fn
151 int 21h
152 mov ah,09h
153 mov al,[show]
154 cmp al,1
155 je w_head
156 lea dx,head
157 int 21h
158 w_head:
159
160
161 mov word ptr[di],2e2ah ;add '*.* ' at the end
162 mov word ptr[di+2],002ah
163
164 l5:
165 lea dx,dta
166 mov ah,1ah
167 int 21h
168 mov ah,4eh ;first fdt matched
169 mov cx,16h ;all file
170 lea dx,fn
171 int 21h
172
173 call outp ;print first file imformation
174 mov cl,1
175 mov count,cl
176 ;-------------
177 ;mov ah,4ch
178 ;int 21h
179 ;-----------
180 l2:
181 mov ah,4fh ;next fdt
182 int 21h
183 jc l0 ;end when no file any more
184
185 call outp ;print next file imformation
186 mov cl,count
187 inc cl
188 mov count,cl
189
190 cmp cl,14h
191 ja pause
192 pause_end:
193 jmp l2
194
195 pause:
196 mov dl,[show]
197 cmp dl,1
198 je pause_end
199 mov ah,9h;move 9 into ah (9 is the interrupt for output)
200 lea dx,msg;move the message into dx
201 int 21h ;call dos function
202 mov ah,7h;move 7 into ah (7 is the interrupt for input)
203 mov dx,00h;get the actual input
204 int 21h ;dos interrupt
205 mov cl,0
206 mov count,cl
207 jmp pause_end
208
209 l0: ;int 20h ;end
210 mov dl,[show]
211 cmp dl,0
212 je not_newline
213
214 mov ah,2 ;new line
215 mov dl,0dh
216 int 21h
217 mov ah,2
218 mov dl,0ah
219 int 21h
220
221 not_newline:
222 lea dx,[space]
223 mov ah,09h
224 int 21h
225 mov al,[filenum]
226 xor ah,ah
227 mov [var_32bits_low],ax
228 xor al,al
229 mov [var_32bits_high],ax
230 call showspace
231
232 lea dx,filespace
233 mov ah,09h
234 int 21h
235
236 mov ax,[used_32bits_high]
237 mov [var_32bits_high],ax
238 mov ax,[used_32bits_low]
239 mov [var_32bits_low],ax
240 call showspace
241 lea dx,bytes
242 mov ah,09h
243 int 21h
244
245
246 lea dx,[space]
247 mov ah,09h
248 int 21h
249
250 mov al,[dirnum]
251 xor ah,ah
252 mov [var_32bits_low],ax
253 xor al,al
254 mov [var_32bits_high],ax
255 call showspace
256
257 lea dx,[dirspace]
258 mov ah,09h
259 int 21h
260 ;-----------------------get free space
261 mov dl,fn[0]
262
263 sub dl,'a'
264 mov ah,36h
265 int 21h
266
267 mul bx
268 mov bx,cx
269 xor cx,cx
270
271 call mymul32
272
273 mov var_32bits_high,cx
274 mov [var_32bits_low],bx
275 call showspace
276
277 lea dx,bytesfree
278 mov ah,09h
279 int 21h
280
281 mov ah,4ch
282 int 21h
283
284
285 p1 endp
286
287 pspace proc near
288 push dx
289 push ax
290 mov dl, ' '
291 mov ah, 2h
292 int 21h
293 pop ax
294 pop dx
295 pspace endp
296
297 printax proc near
298 cmp ax,0
299 je pret
300 push bx
301 push cx
302 push ax
303 push dx
304
305 xor cx,cx
306 ;jmp lable1
307 b11: xor dx,dx
308 lable1: mov si,10
309 div si
310
311 push dx
312 inc cx
313 cmp ax,0
314 jne b11
315
316 b22: pop dx
317 add dl,30h
318 mov ah,2
319 int 21h
320 loop b22
321
322 pop dx
323 pop ax
324 pop cx
325 pop bx
326 pret: ret
327 printax endp
328
329 printax_hex proc near
330 mov cx,4 ; print 4 hex digits (= 16 bits)
331 .print_digit:
332 rol ax,4 ; move the currently left-most digit into the least significant 4 bits
333 mov dl,al
334 and dl,0Fh ; isolate the hex digit we want to print
335 add dl,'0' ; and convert it into a character..
336 cmp dl,'9' ; ...
337 jbe .ok ; ...
338 add dl,7 ; ... (for 'A'..'F')
339 .ok: ; ...
340 push ax ; save EAX on the stack temporarily
341 mov ah,2 ; INT 21H / AH=2: write character to stdout
342 int 21h
343 pop ax ; restore EAX
344 loop .print_digit
345 ret
346 printax_hex endp
347
348 ;----------------------------print the file imfomation--------------------
349 outp proc near
350 push bx
351 push dx
352 push ax
353 push cx
354 mov cx,16
355 lea bx,dta[1eh] ;print name
356 o0:
357 mov dl,[bx]
358 cmp dl,0
359 je o1
360 mov ah,2
361 int 21h
362 dec cx
363 inc bx
364 jmp o0
365
366
367 o1:
368 mov ah,02h ;print space between name and size
369 mov dl,20h
370 int 21h
371 loop o1
372 call b2d ;print size and dir type
373 ;----judge is W
374 mov dl,[show]
375 cmp dl,1
376 je w_file
377 call datm ;print date and time
378
379
380 mov ah,2 ;new line
381 mov dl,0dh
382 int 21h
383 mov ah,2
384 mov dl,0ah
385 int 21h
386 w_file:
387 pop cx
388 pop ax
389 pop dx
390 pop bx
391 ret
392 outp endp
393 ;------------------------------print size-------------------------------------
394 b2d proc near
395 push cx
396 push ax
397 push dx
398 push si
399
400
401 xor cx,cx
402 lea si,dta[1ah]
403 mov ax,[si]
404 call add_used_space
405 call add_filenum
406 cmp ax,0
407 je b4
408 ;----judge is W
409 mov dl,[show]
410 cmp dl,1
411 je b5
412 xor cx,cx
413 b1:
414 xor dx,dx
415 mov si,10
416 div si
417
418 push dx
419 inc cx
420 cmp ax,0
421 jne b1
422 mov si,cx
423
424 b2:
425 pop dx
426 add dl,30h
427 mov ah,2
428 int 21h
429 loop b2
430
431 mov cx,10
432 sub cx,si
433 b3:
434 mov ah,02h
435 mov dl,20h
436 int 21h
437 loop b3
438
439 ;----judge is W
440 mov dl,[show]
441 cmp dl,1
442 je b5
443
444 mov ah,9
445 lea dx,space
446 int 21h
447 jmp b5
448
449 b4:
450 call add_dirnum
451 call sub_filenum
452 ;----judge is W
453 mov dl,[show]
454 cmp dl,1
455 je b5
456 mov ah,09h
457 lea dx,dir
458 int 21h
459
460 b5:
461 pop si
462 pop dx
463 pop ax
464 pop cx
465 ret
466 b2d endp
467
468 add_filenum proc near
469 push ax
470 mov al,[filenum]
471 inc al
472 mov [filenum],al
473 pop ax
474 ret
475 add_filenum endp
476
477 add_dirnum proc near
478 push ax
479 mov al,[dirnum]
480 inc al
481 mov [dirnum],al
482 pop ax
483 ret
484 add_dirnum endp
485
486 sub_filenum proc near
487 push ax
488 mov al,[filenum]
489 dec al
490 mov [filenum],al
491 pop ax
492 ret
493 sub_filenum endp
494
495 ;------------------------------print date and time-----------------------------------------------
496 datm proc near
497 push ax
498 push bx
499 push cx
500 push dx
501 push di
502
503
504 lea bx,dta[18h];data
505 mov di,[bx]
506 mov cx,7;year
507 xor bx,bx
508 d1:
509 shl di,1
510 rcl bx,1
511 loop d1
512 add bx,1980
513 call bi2de
514 mov ah,2
515 mov dl,"."
516 int 21h
517
518 mov cx,4;month
519 xor bx,bx
520 d2:
521 shl di,1
522 rcl bx,1
523 loop d2
524 call bi2de
525 mov ah,2
526 mov dl,"."
527 int 21h
528
529 mov cx,5;day
530 xor bx,bx
531 d3:
532 shl di,1
533 rcl bx,1
534 loop d3
535 call bi2de
536 mov cx,3
537 d7:
538 mov ah,2
539 mov dl," "
540 int 21h
541 loop d7
542
543 ;time
544 lea bx,dta[16h]
545 mov di,[bx]
546 mov cx,5;hour
547 xor bx,bx
548 d5:
549 shl di,1
550 rcl bx,1
551 loop d5
552 call bi2de
553 mov ah,2
554 mov dl,":"
555 int 21h
556 mov cx,6;min
557 xor bx,bx
558 d6:
559 shl di,1
560 rcl bx,1
561 loop d6
562 call bi2de
563
564
565 pop di
566 pop dx
567 pop cx
568 pop bx
569 pop ax
570 ret
571 datm endp
572
573 ;---------------------------------binary2decimal-----------------------------
574 bi2de proc near
575 push ax
576
577 cmp bx,9
578 ja bi0
579 mov ah,2
580 mov dl,'0'
581 int 21h
582 bi0:
583 xor cx,cx
584 mov ax,bx
585 bi1:
586 xor dx,dx
587 mov si,10
588 div si
589
590 push dx
591 inc cx
592 cmp ax,0
593 jne bi1
594
595 bi2:
596 pop dx
597 add dl,30h
598 mov ah,2
599 int 21h
600 loop bi2
601
602 pop ax
603 ret
604 bi2de endp
605
606 ;----------------multiplies dx:ax x cx:bx return dx:ax:cx:bx
607 mymul32 proc near
608
609 push si
610 push di
611 mov si,dx ;save op1hi in si
612 mov di,ax ;save op1lo in di
613 mul bx ;op1l0 x op2lo
614 push ax ;save 1st (32 bit) pp. on stack
615 push dx
616 ;
617 mov ax,si ;op1hi in ax
618 mul bx ;op1hi x op2l0
619 pop bx ;add 2nd (48 bit) pp. to pp1
620 add ax,bx
621 adc dx,0
622 push ax
623 mov bx,dx ;pp1 + pp2 in bx:tos:tos+2
624 ;
625 mov ax,di ;op1lo in ax
626 mul cx ;op1lo x op2hi
627 pop di ;add 3rd (48 bit) pp. to pp1 + pp2
628 add di,ax
629 push di
630 mov di,0
631 adc bx,dx
632 adc di,0 ;pp1+pp2+pp3 in di:bx:tos:tos+2
633 ;
634 mov ax,si ;op1hi in ax
635 mul cx ;op1hi x op2hi
636 add ax,bx ;add 4th (64 bit) pp. to pp1+pp2+pp3
637 adc dx,di
638 pop cx
639 pop bx ;final product in dx:ax:cx:bx
640 ;
641 pop di
642 pop si
643 ret
644 mymul32 endp
645
646 showspace proc near
647 push ax
648 push bx
649 push dx
650 push cx
651 mov ax,0
652 mov bx,0 ;bx: quotidient_32bits_high
653 mov dx,0 ;dx: quotidient_32bits_low
654 mov cx,0 ;counter = 0
655 ;16bits or 32bits ?
656 mov ax,var_32bits_high
657 cmp ax,0
658 jne _32bits_routine
659 jmp _16bits_routine
660
661 ;;;
662 _32bits_routine:
663 mov cx,0
664 ;if == -2147483648 (-2^31)
665 mov ax,var_32bits_high
666 cmp ax,lowest_signed_32bits_high
667 jne check_if_neg
668 mov ax,var_32bits_low
669 cmp ax,lowest_signed_32bits_low
670 jne check_if_neg
671 ;then
672 lea dx,lowest_signed_32bits_string
673 mov ah,9
674 int 21h
675 jmp return_to_dos
676 ;if < 0
677 check_if_neg:
678 mov ax,var_32bits_high
679 cmp ax,0
680 jnl preparations
681 ;then print "-" ...
682 mov ah,2
683 mov dl,'-'
684 int 21h
685 ;... and negate number
686 ;---------xor 0ffffffff , + 1----------
687 mov ax,var_32bits_high
688 xor ax,negate_mask
689 mov var_32bits_high,ax
690 mov ax,var_32bits_low
691 xor ax,negate_mask
692 inc ax
693 mov var_32bits_low,ax
694 jnc preparations
695 mov ax,var_32bits_high
696 inc ax
697 mov var_32bits_high,ax
698 preparations:
699 mov ax,var_32bits_high
700 mov quotidient_32bits_high,ax
701 mov ax,var_32bits_low
702 mov quotidient_32bits_low,ax
703 while_32bits:
704 ; while >0 do
705 mov ax,quotidient_32bits_high
706 cmp ax,0
707 jne div_high_part
708 mov ax,quotidient_32bits_low
709 cmp ax,0
710 jne div_high_part
711 jmp print_char
712 div_high_part:
713 ;divide high part
714 mov dx,0
715 mov ax,quotidient_32bits_high
716 div base_10
717 mov qhigh,ax
718 mov rhigh,dx
719 ;case rhigh
720 mov ax,rhigh
721 cmp ax,0
722 je _rhigh0
723 cmp ax,1
724 je _rhigh1
725 cmp ax,2
726 je _rhigh2
727 cmp ax,3
728 je _rhigh3
729 cmp ax,4
730 je _rhigh4
731 cmp ax,5
732 je _rhigh5
733 cmp ax,6
734 je _rhigh6
735 cmp ax,7
736 je _rhigh7
737 cmp ax,8
738 je __rhigh8
739 cmp ax,9
740 je __rhigh9
741 _rhigh0:
742 mov ax,qhigh0
743 mov qhigh_redundant,ax
744 mov ax,rhigh0
745 mov rhigh_redundant,ax
746 jmp _aftercase
747
748 _rhigh1:
749 mov ax,qhigh1
750 mov qhigh_redundant,ax
751 mov ax,rhigh1
752 mov rhigh_redundant,ax
753 jmp _aftercase
754 __rhigh8:
755 jmp _rhigh8
756 __rhigh9:
757 jmp _rhigh9
758 _rhigh2:
759 mov ax,qhigh2
760 mov qhigh_redundant,ax
761 mov ax,rhigh2
762 mov rhigh_redundant,ax
763 jmp _aftercase
764 _rhigh3:
765 mov ax,qhigh3
766 mov qhigh_redundant,ax
767 mov ax,rhigh3
768 mov rhigh_redundant,ax
769 jmp _aftercase
770 _rhigh4:
771 mov ax,qhigh4
772 mov qhigh_redundant,ax
773 mov ax,rhigh4
774 mov rhigh_redundant,ax
775 jmp _aftercase
776 _rhigh5:
777 mov ax,qhigh5
778 mov qhigh_redundant,ax
779 mov ax,rhigh5
780 mov rhigh_redundant,ax
781 jmp _aftercase
782 _rhigh6:
783 mov ax,qhigh6
784 mov qhigh_redundant,ax
785 mov ax,rhigh6
786 mov rhigh_redundant,ax
787 jmp _aftercase
788 _rhigh7:
789 mov ax,qhigh7
790 mov qhigh_redundant,ax
791 mov ax,rhigh7
792 mov rhigh_redundant,ax
793 jmp _aftercase
794 _rhigh8:
795 mov ax,qhigh8
796 mov qhigh_redundant,ax
797 mov ax,rhigh8
798 mov rhigh_redundant,ax
799 jmp _aftercase
800 _rhigh9:
801 mov ax,qhigh9
802 mov qhigh_redundant,ax
803 mov ax,rhigh9
804 mov rhigh_redundant,ax
805 jmp _aftercase
806 _aftercase:
807 ;divide low part
808 mov ax,0
809 mov q_0,ax
810 mov dx,0
811 mov ax,quotidient_32bits_low
812 div base_10
813 mov qlow,ax
814 mov rlow,dx
815 mov ax,rlow
816 add ax,rhigh_redundant
817 ;if remainder >= 10
818 cmp ax,base_10
819 jl after_if
820 sub ax,base_10
821 mov dx,1
822 mov q_0,dx
823 after_if:
824 mov rlow,ax
825 mov ax,q_0
826 add ax,qlow
827 mov qlow,ax
828 jnc label1
829 mov ax,qhigh
830 inc ax
831 mov qhigh,ax
832 label1:
833 mov ax,qlow
834 add ax,qhigh_redundant
835 mov qlow,ax
836 jnc label2
837 mov ax,qhigh
838 inc ax
839 mov qhigh,ax
840 label2:
841 ;push remainder to stack
842 mov ax,rlow
843 push ax
844 inc cx
845 mov ax,qhigh
846 mov quotidient_32bits_high,ax
847 mov ax,qlow
848 mov quotidient_32bits_low,ax
849 jmp while_32bits
850
851 ;;;
852 _16bits_routine:
853 mov ax,var_32bits_low
854 mov bx,0 ;bx: quotient
855 mov cx,0
856 while_loop:
857 cmp ax,0
858 je print_char
859 mov dx,0
860 div base_10
861 mov bx,ax ;ax stores quotidient
862 mov ax,dx ;dx stores remainder
863 ;push remainder
864 push ax
865 ;counter = counter + 1
866 inc cx
867 ;numerator = quotidient
868 mov ax,bx
869 jmp while_loop
870 print_char:
871 cmp cx,0
872 je return_to_dos
873 pop ax
874 ;because at this point 0 <= ax <= 9, setting ah = 2 does not change the results
875 mov ah,2
876 mov dl,al
877 add dl,30h ;0-> '0',1->'1',....
878 int 21h
879 dec cx
880 jmp print_char
881
882 return_to_dos:
883
884 pop cx
885 pop dx
886 pop bx
887 pop ax
888 ret
889 showspace endp
890
891 ;--------input:ax----------
892 add_used_space proc near
893 push ax
894 push bx
895 push cx
896 push dx
897
898 mov dx,[used_32bits_low]
899 add dx,ax
900 jnc add_finish
901 mov bx,[used_32bits_high]
902 inc bx
903 mov [used_32bits_high],bx
904
905 add_finish:
906 mov [used_32bits_low],dx
907
908 pop dx
909 pop cx
910 pop bx
911 pop ax
912 ret
913 add_used_space endp
914
915 main ends
916 end p1