1-1
实现了一个简单的函数调用。
重点是里面对栈的应用。
call返回时调用ret,后面有一个数字,代表调用时有多少字节数据入栈。
1-2
实现了代码的自我搬移。
include不能放在文件开头,因为程序执行时是从第一行开始。(可能能够重定位,目前未知)
搬移后标记的内存地址都需要重新调整。
当使用短跳转或短call调用的时候,标号不需要调整,因为这里的操作数的间接地址,即两个地址之间的差;当是长跳转或长call调用的时候,操作数是绝对值,需要调整。
访问堆栈的间接寻址中只能使用bp做偏移。
任何时候不要往cs中写东西,要不然程序会崩溃。
1-3
将软盘fat区和根目录区拷贝到内存。
当前内存使用情况:
9000:0000--9000:01ff boot代码,总长512
9000:0200--9000:13ff fat内容,总长1200h
9000:1400--9000:2fff 根目录内容,总长1c00h
fat2文件系统中,前3个字节是跳转指令,后面59字节是磁盘参数,然后是448字节代码区,最后0xaa55引导标记。
现在的问题是编译出的代码过长,只剩下167字节代码段。
下一步考虑使用宏定义代替短函数调用,进一步压缩代码。
1-4
将DispStr改为宏定义之后,成功的将代码压缩了22字节。
包含macro的头文件必须放在文件开头,所以宏定义应该单独放在一个文件中。
loop使用的也是相对偏移量。
使用loop的时候,cx的值就是循环次数,没有加一或减一的偏移。
1-5
当前内存使用情况:
9000:0000--9000:01ff boot代码,总长512
9000:0200--9000:13ff fat内容,总长1200h
9000:1400--9000:2fff 根目录内容,总长1c00h
已经能够找到LOADER.COM文件。
保存在fat2文件系统中文件名都将自动被转换成大写。
在实模式下返回DOS的方法:
%macro RETURNDOS 0 ;这里的0必须要写
mov ax, 4c00h
int 21h
%endmacro
下一步:
加载loader.com
之后内存内容应该为:
9000:0000--9000:01ff boot代码,总长512
9000:0200--9000:13ff fat内容
9000:1400--9000:2fff 根目录内容,总长1c00h
9000:3000--9000:fc00 loader.com
1-6
加载loader.com
此时内存内容为:
9000:0000--9000:01ff boot代码,总长512
9000:0200--9000:13ff fat内容,总长1200h,即4608字节
9000:1400--9000:2fff 根目录内容,总长1c00h
9000:3000--9000:fc00 loader.com,总长0cc00h,即52224字节
最终会跳转到9000:3000
代码地址:
http://d.download.csdn.net/filedown2008/aHR0cDovL2RsMi5jc2RuLm5ldC9kb3duNC8yMDA4MDMzMC8zMDIxMzU0MTgyMi56aXA=!398454