这不是一个asm问题,它是一个DOS系统调用API问题.无论你是用C语言还是直接用asm写作,答案都是一样的.
您需要寻找插入点,并从那里读取所有内容到EOF到内存中.然后编写新数据,然后写入之前的内容.如果这是你可以分配的更多内存,你需要编写一个新文件.(复制开头,写下你的新文本,然后复制结束.)
你可能在想,"为什么你不能告诉操作系统你想要什么,所以它只能修改元数据,而不是强迫你重写数据?".好吧,因为我认为DOS不提供API.此外,因为它只能使用块大小的粒度.如果文件其余部分中的文本现在应该在文件系统数据块中以不同方式排列,则必须重写它.
DOS是为FAT文件系统编写的,而花哨的文件分配操作功能似乎是最近的一项创新.显然,大量使用此操作会导致文件碎片(未在磁盘上连续分配).也许SSD的崛起使得无法在没有碎片的情况下完成的操作更有意义地得到支持,因为Linux已经越来越多地支持这样的操作fallocate(2).
Linux支持将块插入现有文件的中间而不重写它们: fallocate(fd, FALLOC_FL_INSERT_RANGE, offset, len)可用,因为Linux 4.1应该可以解决问题.
自Linux 3.15起,逆操作就可以在不留空的情况下折叠范围.命令行fallocate(1)实用程序支持此功能fallocate -c.
所有这些操作仅适用于文件系统块大小的粒度(通常为4kiB).如果您正在添加或删除那么多的文本,但没有排列在4k边界上,您可以使用fallocate并且只需要重写相邻页面,而不是整个文件的其余部分.
如果您希望能够有效地执行此操作,请在文件中使用类似于文本编辑器的数据结构,以便在任何时候进行有效插入:绳索.一个缺口缓冲区是不是一个好的选择,因为它只能维持在一个时间一个高效的插入点.
在所有文本块之后,可能将"index"放在文件的末尾,因此可以轻松地重写.这意味着您无法将文件提供给其他程序,因为它将采用您的自定义格式.每次需要时,您都需要一个工具来生成平面版本,因此只有在需要修改的时间超过需要读取时(使用不能使用自定义库的程序),磁盘上的Rope才有用.