用汇编写个文件分割器
来源:互联网 发布:卖家怎样开通淘宝客 编辑:程序博客网 时间:2024/04/27 09:31
今天在把宿舍机器上的东西往家里机器上腾的时候,无意中发现了一年多以前用汇编写的一个文件分割器。这一年过去了,一直没有用汇编,也忘得差不多了。再看这个以前自己用汇编写的小程序时,心里有一种莫名的感觉,于是想放到blog上纪念一下。下面是源代码:
; File Splitter V1.0 ; Author: LuPeipei(goodname008) ; Date: 2003.11.29 ; BLOG: http://blog.csdn.net/goodname008 FILE_CREATE EQU 3CH ;Create File FILE_OPEN EQU 3DH ;Open File FILE_READ EQU 3FH ;Read File FILE_WRITE EQU 40H ;Write File FILE_CLOSE EQU 3EH ;Close File FILE_MOVEPTR EQU 42H ;Move File Pointer FILE_DELETE EQU 41H ;Delete File ERR_IFN EQU 01H ;Invalid File Number ERR_FNF EQU 02H ;File Not Found ERR_PNF EQU 03H ;Path Not Found ERR_TMF EQU 04H ;Too Many File opened ERR_RIO EQU 05H ;Refuse Input/Output ERR_IFH EQU 06H ;Invalid File Handler ATTR_ARCHIVE EQU 00H ;File Attrib: Archive ATTR_READONLY EQU 01H ;File Attrib: Read-only ATTR_HIDDEN EQU 02H ;File Attrib: Hidden ATTR_SYSTEM EQU 04H ;File Attrib: System MODE_READ EQU 00H ;File open Mode: Read-only MODE_WRITE EQU 01H ;File open Mode: Write-only MODE_RW EQU 02H ;File open Mode: Read and Write DSEG SEGMENT ERROR_OF DB 'Failed to open file.',0DH,0AH,'$' ERROR_MP DB 'Failed to move the pointer of file.',0DH,0AH,'$' ERROR_FS DB 'The file size must be more than 1MB and less than 4096MB.',0DH,0AH,'$' ERROR_VC DB 'The number of volume must be more than 1 and less than 100.',0DH,0AH,'$' ERROR_CF DB 'Falied to create file.',0DH,0AH,'$' ERROR_WF DB 'Insufficient disk space.',0DH,0AH,'$' COMPLETE DB 'Complete successfully!!!',0DH,0AH DB 'Thank you for using this software.',0DH,0AH,'$' LOGO DB 'LPP (R) File Splitter version 1.0',0DH,0AH DB 'Copyright (C) LPP software studio 2003-2004. All rights reserved.',0DH,0AH,0DH,0AH DB 'Options: 1 -- Split 2 -- Combine',0DH,0AH,0DH,0AH DB 'Your choice: $' PROMPTSF DB 'Source filename: $' FILESIZE DB 'File size: ',8 DUP('$') OPTIONSIZE DB 'Volume size options: 1 -- Floppy Disk (1.44 MB) 2 -- Custom.',0DH,0AH,0DH,0AH DB 'Your choice: $' PROMPTS DB 'Volume size(MB): $' PROMPTTF DB 'Target filename(don',"'",'t input extend name): $' SFSIZE DD ? TFSIZE DW ? SFNUM DW ? TFNUM DW ? SFNAME DB 65,?,65 DUP(0),'$' TFNAME DB 65,?,65 DUP(0),'.ext',0,'$' VSIZE DB 4,?,4 DUP(0),'$' PDIGIT DB 0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9 BUFFER DB 60736 DUP(?),'$' FLAG DB ? DSEG ENDS SSEG SEGMENT STACK DB 100 DUP(?) SSEG ENDS CSEG SEGMENT ASSUME CS:CSEG,DS:DSEG,SS:SSEG START: MOV AX,DSEG MOV DS,AX LEA DX,LOGO ;print Author ,Copyrights and options MOV AH,9H INT 21H MOV AH,1H ;get user choice INT 21H CALL PRINTCRLF CMP JE CMP JE COMBINE MOV AH,4CH INT 21H COMBINE:CALL COMBINEMODULE ;---------------------------------------------------------------------------- COMBINEMODULE PROC MOV PROMPTTF[15],':' MOV PROMPTTF[16],' ' MOV PROMPTTF[17],'$' LEA DX,PROMPTTF ;print "Target filename:" MOV AH,9H INT 21H LEA DX,TFNAME ;get the target filename from user MOV AH,0AH INT 21H MOV DL,TFNAME+1 ;set the last filename char to 0 XOR DH,DH MOV DI,DX MOV TFNAME[DI+2],0 CALL PRINTCRLF LEA DX,TFNAME+2 ;create target file MOV AH,FILE_CREATE MOV CX,ATTR_ARCHIVE INT 21H MOV TFNUM,AX ;save target file number to TFNUM JNC COK_CF ;if error then EXIT LEA DX,ERROR_CF MOV AH,9H INT 21H MOV AH,4CH INT 21H COK_CF: LEA DX,PROMPTSF ;print "Source filename:" MOV AH,9H INT 21H LEA DX,SFNAME ;get the source filename from user MOV AH,0AH INT 21H CALL PRINTCRLF MOV DL,SFNAME+1 ;set the last filename char to 0 XOR DH,DH MOV DI,DX LEA DI,SFNAME[DI] ;source filename extendsion's number --> DI MOV BYTE PTR [DI+2],0 MOV BYTE PTR [DI+3],'$' CALL PRINTCRLF CALL PRINTCRLF MOV TFSIZE,0FFFFH ;copy 1048576 bytes per time XOR AX,AX C_NEXT: PUSH AX CALL HEXTODECASC ;change source file extend name MOV BX,AX LEA DX,SFNAME+2 ;open source file MOV AH,FILE_OPEN MOV AL,MODE_READ INT 21H MOV SFNUM,AX ;save source file number JNC COK_OF ;if error then EXIT CMP BX,0 ;if complete the EXIT JNE EXITCSU CALL PRINTCRLF LEA DX,ERROR_OF ;print "Falied to open file." MOV AH,9H INT 21H MOV AH,4CH INT 21H EXITCSU:CALL PRINTCRLF LEA DX,COMPLETE ;print "Complete successfully ..." MOV AH,9H INT 21H MOV AH,4CH INT 21H COK_OF: LEA DX,SFNAME+2 ;print source filename MOV AH,9H INT 21H MOV DL,'.' ;print "......" MOV AH,2H INT 21H INT 21H INT 21H INT 21H INT 21H INT 21H CALL PRINTCRLF CCOPY: CALL COPYBYTES JC EXITCWF ;if disk full then EXIT CMP FLAG,1 ;if complete then EXIT JNE CCOPY MOV BX,SFNUM ;close source file MOV AH,FILE_CLOSE INT 21H POP AX INC AX JMP C_NEXT EXITCWF:CALL PRINTCRLF LEA DX,ERROR_WF ;print "Insufficient disk space." MOV AH,9H INT 21H MOV AH,4CH INT 21H COMBINEMODULE ENDP ;---------------------------------------------------------------------------- SPLITMODULE PROC LEA DX,PROMPTSF ;print "Source filename:" MOV AH,9H INT 21H LEA DX,SFNAME ;get the source filename from user MOV AH,0AH INT 21H CALL PRINTCRLF MOV DL,SFNAME+1 ;set the last filename char to 0 XOR DH,DH MOV SI,DX MOV SFNAME[SI+2],0 CALL PRINTCRLF LEA DX,SFNAME+2 ;open source file MOV AH,FILE_OPEN MOV AL,MODE_READ INT 21H JNC SOK_OF ;if error then EXIT LEA DX,ERROR_OF MOV AH,9H INT 21H MOV AH,4CH INT 21H SOK_OF: MOV SFNUM,AX ;save source file number MOV BX,AX XOR CX,CX ;get the length of file(Bytes) --> DX:AX XOR DX,DX MOV AL,02H MOV AH,FILE_MOVEPTR INT 21H JNC SOK_MP ;if error occured then EXIT LEA DX,ERROR_MP MOV AH,9H INT 21H MOV AH,4CH INT 21H SOK_MP: CMP DX,0010H ;if the length of file is less than 1MB or more than 4096MB then EXIT JB EXIT_FS CMP DX,0FFF0H JNA SOK_FS EXIT_FS:LEA DX,ERROR_FS MOV AH,9H INT 21H MOV AH,4CH INT 21H SOK_FS: MOV WORD PTR SFSIZE,AX MOV WORD PTR SFSIZE+2,DX MOV AX,DX ;the length of file(MB) --> AX MOV CL,4 SHR AX,CL PUSH AX ;save the length of file to stack MOV DX,AX LEA BX,FILESIZE[11] CALL HEXTODECASC5 MOV FILESIZE[DI+11],'.' MOV FILESIZE[DI+12],'0' MOV AX,WORD PTR SFSIZE+2 AND AX,000FH ;calculate the point part ( LEA BX,PDIGIT XLAT MOV DX,AX LEA BX,FILESIZE[DI+12] CALL HEXTODECASC5 MOV FILESIZE[SI+11+1],'0' LEA DX,FILESIZE MOV AH,9H INT 21H MOV AH,2H ;show ' MB' after source file size MOV DL,' ' INT 21H MOV DL,'M' INT 21H MOV DL,'B' INT 21H CALL PRINTCRLF CALL PRINTCRLF MOV BX,SFNUM ;set file pointer to 0000:0000 XOR CX,CX XOR DX,DX MOV AL,00H MOV AH,FILE_MOVEPTR INT 21H LEA DX,OPTIONSIZE ;print volume size options information MOV AH,9H INT 21H MOV AH,1H ;get user choice INT 21H CALL PRINTCRLF CMP AL,'1' ;1 -- Floppy Disk (1.44 MB) 2 -- Custom. JE FLP CMP JE CUSTOM MOV AH,4CH INT 21H ;if FLOPPY then check file size FLP: CMP WORD PTR SFSIZE+2,0016H JB EXIT_VC JE CMPLOW MOV AX,WORD PTR SFSIZE+2 CMP AX,8B0H JA EXIT_VC JMP SOK_VC CMPLOW: CMP WORD PTR SFSIZE,3E00H JB EXIT_VC JMP SOK_VC CUSTOM: LEA DX,PROMPTS ;print "Volume size:" MOV AH,9H INT 21H LEA DX,VSIZE ;get volume size to AX (n:MB) CALL RECEIVENUM LEA DX,VSIZE+2 CALL ASCTOHEX CALL BCDTOHEX CMP AX,0 JE EXIT_VC MOV SI,AX ;AX --> SI (volume size, n:MB) MOV TFSIZE,AX ;save volume size to memory POP AX ;restore the length of file from stack XOR DX,DX ;volume count --> AX (actually in DIV SI CMP AX,0 ;if volume count = 0 or more than 100 then EXIT JE EXIT_VC CMP AX,64H JNA SOK_VC EXIT_VC:LEA DX,ERROR_VC MOV AH,9H INT 21H MOV AH,4CH INT 21H SOK_VC: LEA DX,PROMPTTF ;print "Target filename:" MOV AH,9H INT 21H LEA DX,TFNAME ;get the target filename from user MOV AH,0AH INT 21H CALL PRINTCRLF MOV DL,TFNAME+1 ;set the last filename char to '.' XOR DH,DH MOV SI,DX MOV TFNAME[SI+2],'.' ;set target filename format "X:/********.Lnn" MOV TFNAME[SI+3],'L' LEA DI,TFNAME[SI+4] ;target filename extendsion's number --> DI MOV BYTE PTR [DI+3],'$' MOV BYTE PTR [DI+2],0 ;set the last filename char to 0 XOR AX,AX ;the first volume name is *.L00 CALL PRINTCRLF S_NEXT: PUSH AX ;save the last two extension (.L**) to stack CALL HEXTODECASC ;set target filename extension (.Lnn) LEA DX,TFNAME[2] ;print filename (volume) MOV AH,9H INT 21H MOV DL,'.' ;print "......" after filename MOV AH,2H INT 21H INT 21H INT 21H INT 21H INT 21H INT 21H CALL PRINTCRLF LEA DX,TFNAME[2] ;create target file (volume) MOV CX,ATTR_ARCHIVE MOV AH,FILE_CREATE INT 21H JNC SOK_CF ;if error occurs then EXIT LEA DX,ERROR_CF MOV AH,9H INT 21H MOV AH,4CH INT 21H SOK_CF: MOV TFNUM,AX ;save file number to TFNUM MOV CX,TFSIZE ;copy (1048576 * volume size) bytes JCXZ CPYFLP COPY: CALL COPYBYTES JC EXIT_WF ;if disk full then EXIT CMP FLAG,1 ;if complete then EXIT JE EXIT_SU JMP CLOSE CPYFLP: CALL COPYBYTES ;copy 1457664 (1.44 MB) bytes JC EXIT_WF ;if disk full then EXIT CMP FLAG,1 ;if complete then EXIT JE EXIT_SU CLOSE: MOV BX,TFNUM ;close target file (volume) MOV AH,FILE_CLOSE INT 21H POP AX ;restore the last two extension (.L**) from stack INC AX JMP S_NEXT EXIT_WF:CALL PRINTCRLF LEA DX,ERROR_WF ;print "Insufficient disk space." MOV AH,9H INT 21H JMP EXIT EXIT_SU:CALL PRINTCRLF LEA DX,COMPLETE ;print "Complete successfully ......" MOV AH,9H INT 21H EXIT: MOV BX,TFNUM ;close target file (the LAST volume!!!) MOV AH,FILE_CLOSE INT 21H MOV BX,SFNUM ;close source file INT 21H MOV AH,4CH INT 21H SPLITMODULE ENDP ;---------------------------------------------------------------------------- ;Proc Name: COPYBYTES ;Function: copy some bytes (1MB or 1.44MB) from SFNUM (source file number) to TFNUM(target file number) ;Parameter: (none, actually in the memory TFSIZE,SFNUM,TFNUM) ;RetValue: CF: if there are not enough bytes for reading, CF = 1 ;Notice: (1) it can be only used in this program!!!!! COPYBYTES PROC PUSH AX PUSH BX PUSH CX PUSH DX PUSH SI PUSH DI MOV FLAG,0 MOV SI,24 ;repeat 24 times, copy 60736 bytes per time MOV DI,60736 ;24 * 60736 = 1457664 (1.44 MB) CMP TFSIZE,0 JE C_READ MOV SI,32 ;repeat 32 times, copy 32768 bytes per time MOV DI,32768 ;32 * 32768 = 1048576 C_READ: MOV BX,SFNUM ;read DI bytes from source file MOV CX,DI LEA DX,BUFFER MOV AH,FILE_READ INT 21H CMP AX,CX ;check out: whether read DI bytes or not JE C_WRITE MOV FLAG,1 C_WRITE:MOV BX,TFNUM ;write DI bytes to target file MOV CX,AX LEA DX,BUFFER MOV AH,FILE_WRITE INT 21H STC CMP AX,CX ;if disk full then return (CF = 1) JNE C_RET CMP FLAG,1 ;if complete then return (FLAG = 1) JE C_CLC DEC SI JNZ C_READ C_CLC: CLC C_RET: POP DI POP SI POP DX POP CX POP BX POP AX RET COPYBYTES ENDP ;Proc Name: BCDTOHEX ;Function: Convert BCD number to HEX number ;Parameter: AX = the BCD number ;RetValue: AX = the HEX number ;Notice: (1) algorithm: ; BCD - (8 * C18 + 4 * ; 8421 - (8 * C18 + 4 * BCDTOHEX PROC PUSH BX PUSH CX PUSH DX PUSH SI MOV BX,AX ; 2 * 6 MOV CL,4 SHR AL,CL XOR AH,AH MOV CH,6 MUL CH MOV SI,AX ; 2 * 6 --> SI MOV AL,BH ; 4 * AND MOV CH,9CH MUL CH XOR DX,DX ; 4 * ADD AX,SI MOV SI,AX ; 4 * MOV AL,BH ; 8 * C18 SHR AL,CL XOR AH,AH MOV CX, MUL CX ADD AX,SI ; 8 * C18 + 4 * MOV SI,AX ; 8 * C18 + 4 * MOV AX,BX ; 8421 - (8 * C18 + 4 * SUB AX,SI POP SI POP DX POP CX POP BX RET BCDTOHEX ENDP ;Proc Name: RECEIVENUM ;Function: Receive a number from keyboard (Decimal) ;Parameter: DX = the first address of the buffer ;RetValue: Bytes in buffer (i.e. '0018') ;Notice: (1) the first byte from DX is the length of number you want receive ; (2) the second byte from DX is the length of number you inputed actually ; (3) the buffer is not include [ENTER] RECEIVENUM PROC PUSH SI PUSH AX PUSH BX PUSH CX PUSH DX MOV SI,DX ;save the length to BL,CL MOV BL,BYTE PTR [SI] MOV CL,BYTE PTR [SI] XOR CH,CH R_AGN: MOV AH,8H ;waiting input INT 21H CMP AL,0DH ;if [ENTER] then save number string and return JE R_ENT CMP AL,8 ;if [BACKSPACE] then delete the last number JE R_BACK CMP CL,0 ;if get the length then BEEP JE R_BEEP CMP AL,'0' ;if '0' <= ASCII <= '9' then SHOW else BEEP JB R_BEEP CMP JBE R_SHOW R_BEEP: MOV DL,7H ;BEEP and receive again MOV AH,2H INT 21H JMP R_AGN R_SHOW: MOV DL, MOV AH,2H INT 21H MOV BYTE PTR [SI+2], INC SI LOOP R_AGN ;receive again JMP R_AGN ;*** when CX = 0, don't execute R_BACK R_BACK: CMP CL,BL ;avoid deleting extra character JE R_AGN MOV DL,8 ;show [BACKSPACE] MOV AH,2H INT 21H MOV DL,' ' ;clear current cursor's position INT 21H MOV DL,8 ;show [BACKSPACE] again INT 21H CMP CX,0 ;if CX = 0 then not save it to memory JE R_BAGN MOV BYTE PTR [SI+2],0 R_BAGN: DEC SI INC CX JMP R_AGN R_ENT: MOV DL,0DH ;finish inputing, print 0DH,0AH MOV AH,2H INT 21H MOV DL,0AH INT 21H POP DX ;restore DX MOV SI,DX ;save actually length MOV AL,BYTE PTR [SI] XOR AH,AH SUB AL,CL MOV BYTE PTR [SI+1], CMP AL,0 ;if input nothing or input full length then RETURN JE R_RETN CMP AL,BL JE R_RETN MOV BX,AX ;add leading-zero (i.e. '0018') MOV CX,BX R_PRE0: MOV AL,[SI+BX+1] MOV [SI+5], MOV BYTE PTR [SI+BX+1],0 DEC SI R_RETN: POP CX POP BX POP AX POP SI RET RECEIVENUM ENDP ;Proc Name: ASCTOHEX ;Function: ASCII to HEX number ;Parameter: DX = the first address of the 4 bytes that you want to convert ;RetValue: AX = the HEX number ;Notice: (1) no error handling ; (2) not (HIGH HIGH LOW LOW) ASCTOHEX PROC PUSH BX PUSH CX PUSH DX PUSH SI MOV CL,4 MOV SI,DX ;1 MOV BX,SI CALL ASCTOHEX_BYTE MOV AH,DL ;AX: 0000 1111 0000 0000 INC SI ;2 MOV BX,SI CALL ASCTOHEX_BYTE MOV SHL SHL AX,CL ;AX: 1111 2222 0000 0000 INC SI ;3 MOV BX,SI CALL ASCTOHEX_BYTE MOV DH,DL ;DX: 0000 3333 0000 0000 INC SI ;4 MOV BX,SI CALL ASCTOHEX_BYTE ;DX: 0000 3333 0000 4444 SHL DL,CL ;DX: 0000 3333 4444 0000 SHR DX,CL ;DX: 0000 0000 3333 4444 MOV POP SI POP DX POP CX POP BX RET ASCTOHEX ENDP ;Proc Name: ASCTOHEX_BYTE ;Function: ASCII to HEX number by byte ;Parameter: BX = address of the byte that you want to convert ;RetValue: DL = the HEX number ;Notice: (1) no error handling ASCTOHEX_BYTE PROC MOV DL,[BX] CMP DL,'0' JAE AE_0 JMP EXIT_P AE_0: CMP DL,'9' JBE BE_9 CMP DL,'A' JAE AE_DA JMP EXIT_P BE_9: SUB DL,30H JMP EXIT_P AE_DA: CMP DL,'Z' JBE BE_DZ CMP DL,'a' JAE AE_XA JMP EXIT_P BE_DZ: SUB DL,37H JMP EXIT_P AE_XA: CMP DL,'z' JBE BE_XZ JMP EXIT_P BE_XZ: SUB DL,57H EXIT_P: RET ASCTOHEX_BYTE ENDP ;Proc Name: HEXTODECASC ;Function: Convert HEX number to ASCII string of Decimal number ;Parameter: ; DI = the base pointer that the result will save in, buffer size must be 2. ;RetValue: 2 bytes from the base pointer(DI) in data segment HEXTODECASC PROC PUSH AX PUSH CX PUSH DX PUSH DI MOV DL,10 MOV CX,2 H_NEXT: XOR AH,AH DIV DL ADD AL,30H MOV [DI], INC DI MOV DL,1 MOV POP DI POP DX POP CX POP AX RET HEXTODECASC ENDP ;Proc Name: HEXTODECASC5 ;Function: Convert HEX number to ASCII string of Decimal number ;Parameter: DX = the HEX number you want to convert ; BX = the base pointer that the result will save in, buffer size must be 5. ;RetValue: DI = the number of digit ; 5 bytes from the base pointer(BX) in data segment ;Notice: (1)Variable NUMBER must not be appear in data segment of main procedure ; (2)The tag of segment in main procedure must be "DSEG" HEXTODECASC5 PROC DSEG_DENO SEGMENT NUMBER DW 10000,1000,100,10,1 DSEG_DENO ENDS PUSH SI PUSH AX PUSH CX PUSH DX PUSH DS XOR SI,SI XOR DI,DI MOV CX,5 H5_NEXT:MOV AX,DX MOV DX,DSEG_DENO MOV DS,DX XOR DX,DX DIV WORD PTR [SI] CMP JZ H5_ZERO ADD AL,30H PUSH BX MOV BX,DSEG MOV DS,BX POP BX MOV [BX][DI],AL INC DI H5_ZERO:ADD SI,2 ;MOV BYTE PTR [BX][DI],'M' ;spcial in this program POP DS POP DX POP CX POP AX POP SI RET HEXTODECASC5 ENDP ;Proc Name: PRINTCRLF ;Function: Set the next print position to next line ;Parameter: (none) PRINTCRLF PROC PUSH AX PUSH DX MOV AH,2H MOV DL,0DH INT 21H MOV DL,0AH INT 21H POP DX POP AX RET PRINTCRLF ENDP CSEG ENDS END START |
汇编这种语言,只要一放下,就不太容易再捡起来了。但通过学习汇编可以对计算机的底层机制有一个更深层次的了解,而这种了解是不会让人轻易忘记的,并且对今后使用高级语言编程时有很大的好处。
上面的这个用于文件分割的小程序也是我初学汇编时写的,有些想法可能并不尽如人意,还希望高手多多指点。
*-------------------------------------------*
* 转载请通知作者并注明出处,CSDN欢迎您! *
* 作者:卢培培(goodname008) *
* 邮箱:goodname008@163.com *
* 专栏:http://blog.csdn.net/goodname008 *
*-------------------------------------------*
- 用汇编写个文件分割器
- 用C++写一个文件分割器
- 没鸟事 写个汇编加法
- 用sqlserver手动写个split(字符分割)
- 用汇编写的第一个程序---helloworld.asm
- 用汇编写个最小的WDM驱动程序进RING0
- 用汇编写个字符型的flappy bird
- 用汇编写个字符型的flappy bird
- VC 写 TXT 文件分割器 附代码
- 用pytho写的分割pdb文件一个脚本
- 用debug写汇编
- 自己写的文件分割的程序
- 【反汇编软件分享】写了个Android系统下的x86反汇编器,欢迎捧场
- WIN32 汇编写病毒感染PE文件
- 文件分割器
- 文件分割器
- 文件分割器
- 文件分割器
- 在asp.net中写Cookie,供asp读出
- LookupDispatchActionSupport和DispatchActionSupport的最大不同
- 使win2003支持asp
- 为一套房子你要奋斗多少年?(转帖)
- struts的三种转向方式
- 用汇编写个文件分割器
- 全球供应链软件研究中心在厦门设立
- 朗讯笔试题目--C语言部分(zz)
- 物流管理促使ERP变革
- Linux下PCI设备驱动开发
- 优秀学习资源站点集锦
- 用单例模式实现的java连接MySql数据库
- 阻塞套接字封装类-头文件
- 阻塞套接字类-CPP文件