- UID
- 1
- 精华
- 积分
- 76365
- 威望
- 点
- 宅币
- 个
- 贡献
- 次
- 宅之契约
- 份
- 最后登录
- 1970-1-1
- 在线时间
- 小时
|
之前我生成软盘镜像用的是UltraISO,使用它来将一个个文件拷进一个3.5英寸软盘镜像里,就像下图这样。。
偶尔我也通过使用VMware虚拟机生成一个空的软盘镜像,然后用虚拟机Windows将其格式化并往里面添加文件。。
这两种方法都……是手动的。我不喜欢这样。然而我也懒得直接用C或者VB写一个自动的制造软盘镜像的东西。我想用一个更加方便的方式来完成。。
于是我就写了一个汇编的inc文件,用nasm编译一个汇编的“脚本”来生成一个软盘镜像(虽然这似乎更麻烦了)
你只需要包含我的inc然后像这样写代码,就可以生成一个有文件的软盘镜像了!- %include"flpbuild.inc"
- flp_start
- ;设置卷标
- flp_add_empty_file "FLPBUILD",A_VolLabel
- ;添加文件
- flp_add_file "build.bat", "BUILD BAT",A_Normal|A_ReadOnly
- flp_add_file "picture.jpg", "PICTURE JPG",A_Normal
- flp_add_file "flpbuild.inc","FLPBUILDINC",A_Normal
- flp_add_file "flp.asm", "FLP ASM",A_Normal
- flp_end
复制代码 (虽然文件不能一个一个地添加,而且也不能添加子文件夹,不过这好歹是可以自动化的)
用这种方法“编译”出来的img文件可以用UltraISO正常打开、查看里面的文件。
软盘使用的是FAT12文件系统,对于这个文件系统,它有个DBR引导扇区,2个FAT表,1个根目录表,和数据区。如何才能让汇编器分别往这几个不同的地方都添加自己想要添加的东西呢?用“段”来实现。
通常情况下我们编写汇编语言程序的时候,都会定义.text段(即代码段)、.data段(数据段)等。不同的段被用于存储不同类型的数据,这些段单独存在,不会被拆开存储。因此我们可以巧妙利用这一特性,通过分段来让汇编器把我们生成的字节丢到不同的位置,最后再把这些段拼接起来,形成一个完整的文件。
然后我们用编译DOS的.COM后缀的程序的方法,让nasm“编译”我们的软盘就行了。生成的文件是.COM程序那样的平坦结构模型,因此所有的段都是直接连在一起的。这正好符合我们的需求——将软盘镜像的DBR扇区、FAT表、根目录、数据区等连接在一起。
现在放上flpbuild.inc的内容——- ;FLP文件构建器
- ;作者:0xAA55
- ;网站:http://www.0xaa55.com
- ;请保留原作者信息。
- ;用法:
- ;1、建立新的汇编文件
- ;2、包含这个头文件
- ;3、使用flp_start宏,进行初始化操作
- ;4、使用flp_add_file宏来添加文件,参数详见宏定义。
- ; 或者使用flp_add_empty_file来添加空白文件。
- ; 你可以重复使用上面的宏来添加多个文件。
- ; 补充:添加文件之前,你还可以调用flp_set_create_time来设置文件的创建时间,或
- ; flp_set_last_write_time来设置文件的最后写入时间。
- ;5、最后,调用flp_end结束(会填充0来完成整个镜像文件的构造)
- %macro fn8_3 1
- %%SFN db %1
- times 11-($-%%SFN) db " "
- %endmacro
- %define MakeTime(h,m,s) (((s>>1)&0x1f)|((m&0x3f)<<5)|((h&0x1f)<<11))
- %define MakeDate(y,m,d) ((d&0x1f)|((m&0xf)<<5)|(((y-1980)&0x7f)<<9))
- ;文件属性位
- %define A_Normal 0x00
- %define A_ReadOnly 0x01
- %define A_Hidden 0x02
- %define A_System 0x04
- %define A_VolLabel 0x08
- %define A_LFNItem 0x0F
- %define A_Directory 0x10
- %define A_Archive 0x20
- ;宏名:flp_set_create_time
- ;描述:设置文件创建的日期和时间
- ;参数:
- ;MakeTime(时间)
- ;MakeDate(日期)
- %macro flp_set_create_time 2
- %define _flp_cdate %1
- %define _flp_ctime %2
- %endmacro
- ;宏名:flp_set_last_write_time
- ;描述:设置文件创建的日期和时间
- ;参数:
- ;MakeTime(时间)
- ;MakeDate(日期)
- %macro flp_set_last_write_time 2
- %define _flp_wdate %1
- %define _flp_wtime %2
- %endmacro
- ;宏名:flp_write_cluster_number
- ;描述:在FAT表写入簇号
- %macro flp_write_cluster_number 1
- %assign cur_clus_num (%1)&0xfff
- %if curclus & 1
- segment fat1
- db last_clus_num & 0xff
- db ((last_clus_num>>8) & 0xf) | ((cur_clus_num & 0xf)<<4)
- db cur_clus_num >> 4
- segment fat2
- db last_clus_num & 0xff
- db ((last_clus_num>>8) & 0xf) | ((cur_clus_num & 0xf)<<4)
- db cur_clus_num >> 4
- %endif
- %assign curclus curclus+1
- %assign last_clus_num cur_clus_num
- %endmacro
- ;宏名:flp_write_cluster_end
- ;描述:在FAT表簇链中写入末簇
- %macro flp_write_cluster_end 0
- flp_write_cluster_number 0xfff
- %endmacro
- ;宏名:flp_write_seq_clus
- ;描述:在FAT表簇链中写入有序的簇号
- ;参数:
- ;簇数
- %macro flp_write_seq_clus 1
- %if %1>1
- %rep %1-1
- flp_write_cluster_number curclus+1
- %endrep
- %endif
- flp_write_cluster_end
- %endmacro
- ;宏名:flp_start
- ;描述:开始构建FLP文件
- %macro flp_start 0
- segment dbr
- incbin"dbr.bin"
- segment fat1
- segment fat2
- segment root
- segment data
-
- flp_set_create_time MakeDate(2015,12,11),MakeTime(23,0,0)
- flp_set_last_write_time MakeDate(2015,12,11),MakeTime(23,0,0)
-
- %assign curclus 0
- flp_write_cluster_number 0xff0
- flp_write_cluster_number 0xfff
- %endmacro
- ;宏名:flp_add_empty_file
- ;描述:添加空文件到根目录区
- ;参数:
- ;短文件名
- ;文件属性
- %macro flp_add_empty_file 2
- segment root
- fn8_3 %1
- db %2
- db 0
- db 0
- dw _flp_ctime
- dw _flp_cdate
- dw _flp_wdate
- dw 0
- dw _flp_wtime
- dw _flp_wdate
- dw 0
- dd 0
- %endmacro
- ;宏名:flp_add_file
- ;描述:添加文件到根目录区
- ;参数:
- ;文件名
- ;短文件名
- ;文件属性
- %macro flp_add_file 3
- ;先将文件添加到数据区
- segment data
- %%SOF:
- incbin %1
- %%EOF:
- %%LOF equ %%EOF-%%SOF
- %if %%LOF
- %%StartClus equ (%%SOF-$$)/512+2
- %%NbClus equ (%%LOF-1)/512+1
- times 512*%%NbClus-%%LOF db 0
- %else
- %%StartClus equ 0
- %%NbClus equ 0
- %endif
- ;然后在根目录添加目录项
- segment root
- fn8_3 %2
- db %3
- db 0
- db 0;文件创建时间的十毫秒数
- dw _flp_ctime
- dw _flp_cdate
- dw _flp_wdate
- dw %%StartClus>>16
- dw _flp_wtime
- dw _flp_wdate
- dw %%StartClus
- dd %%LOF
-
- ;之后更新FAT表
- flp_write_seq_clus %%NbClus
- %endmacro
- ;宏名:flp_end
- ;描述:结束FLP文件的构建,做收尾工作
- %macro flp_end 0
- %if curclus & 1
- flp_write_cluster_end
- %endif
- segment fat1
- times 9*512-($-$$) db 0
- segment fat2
- times 9*512-($-$$) db 0
- segment root
- times 14*512-($-$$) db 0
- segment data
- times 2847*512-($-$$) db 0
- %endmacro
复制代码 通过使用这些宏,我们就可以生成一个软盘镜像文件了。
用flp_add_empty_file来添加空文件,然后用flp_add_file来添加文件。
但是就目前而言,这东西不能添加文件夹,不能往文件夹里添加文件,并且不支持长文件名。不过我们可以在现在用的这些宏的基础之上,添加一些新的宏,比如,写一个新的宏使其在添加文件的时候,将目录项添加到别的地方而不是root段(这个“别的地方”就是我们的子文件夹的内容了)并修改flp_end来将子文件夹放在数据区的最后(同时还要保证FAT表也同步)。。当然还有更好的办法只是我还没想出来而已。现在先这么用吧。等到需要的时候——我们还是干脆用C语言写个生成软盘镜像的东西吧。
flpbuild.7z
(99.15 KB, 下载次数: 2, 售价: 1 个宅币)
参考资料:
http://www.0xaa55.com/thread-5-1-1.html
类似的例子:使用汇编构造一个ico图标文件或cur光标文件
http://www.0xaa55.com/thread-1204-1-1.html |
|