自己编写操作系统的笔记2

今天再次研究了boot.asm。

首先解决昨天的问题:

1。我编译好的exe有1009B,用exe2com转换后com文件才497字节,并不是原来的512B。按说这样的0xAA55h不在正确的位置,但是写入后居然可以启动。

关于这个我想我找到了解决办法。首先是不再使用exe2bin,直接用UltraEdit打开将近32k的exe,把7e00h前的二进制删除,保存,此时文件正好512b。将后缀改为bin,然后写入img文件,加载启动,成功。不过代码稍有改动,第二点将详细说明。

2.org 07c0h不能使用,否则编译后程序有31k之巨,也不能写入磁盘。那么这个org究竟是什么用?怎么会使编译后的程序变大?按说它只在运行时影响内存才对。

原先有31K,我想跟org 这句有不小的关系。那个宏定义总是让人不舒服,现在采用这句:

db 510-($-[start]) dup(0)

我不得不承认我原先没有过多的编写汇编程序,连书后习题也没怎么做过。今天也是突然想起来这句,比于源在nasm里使用的方便许多,事实证明这句确实有用。

3.rept 510-($-seg start)  始终对这句话不放心,这句话能可靠地把AA55放到511和512吗?结果看来是这样的,但是boot.bin只有497B,很不放心。

如上解决,确信是org的问题。恐怕masm十分省事地在07c00h前填0了事,这样就不用在每个寻址处计算地址了。这就是为什么编译后有32K的原因吧。

4.说前三个问题时我没有注释掉这三行

; rept 510-($-seg start)  ;填满至510B
; db 0
; endm

现在注释掉了,编译并且转换后程序才48B,但是正常启动了。这回的AA55h肯定不在应该在的地方了,可是还是正常启动, 跟已知是不符的。

只能说可能是现在的BIOS更智能了?发现1st boot device有启动代码就会尝试启动吧。不过既然有标准,就应该按照标准去做,现在使用新的方法已经非常接近nasm做出的结果了,除了生成的地址不一致,以及编译后的代码比原先少了一B(就是说比nasm的多填一个0,所以总大小仍为512B)

 

 

 

现在看看我今天发现的东西吧:

1.org 07c0h 究竟有没有用?答案是绝对有用。PC开机确实是把boot sector加载到这个地址,所以如果没有加上这句,程序中所有的地址都没有07c0h的偏移,访问数据就会出错,也就是ds指向错误。但是可不可以不用它呢?答案是可以的。既然ds错误,那么让它正确不就可以了?所以mov ax,07c0h     mov ds,ax这两句过后就正确了,而且link后程序仅1k。注意,mov的是07c0h,因为寻址的地址ds要左移四位,就是07c00h了。当然,还是需要将200h前的二进制删除,删除后仍然512B。不过这种办法比org的版本二进制代码又多了1B。

2.我使用的masm是615版本,很遗憾,这个版本似乎为与想象中的汇编差距大了许多。比如上边说了,需要手动删除一些才能使用。删除的都是0吗?不是,这里有8B的二进制代码。这应该是msam的link多此一举了,肯定是为系统建立某些传送信息的堆栈。当然,不删除的话写到img里是会出错的。

3.两种方法的优劣:先说一下org版。这个版本编译后不必修改就可以直接看它在dos窗口中打出红色的字符串来,甚至不必像作者用org 0100h来调试,实在是方便。这是因为那个org使得数据在win下的加载位置已经偏移了(所以才32k啊,都是masm搞的鬼)。而mov的办法十分狂野,在win下也不会打出字来,因为数据加载位置没有变化,但是ds已经指向数据理应加载的位置。不过有一点要注意:删除了那些0后在win下就不能正确寻址了,所以不要用512B的bin去调试了。

 

最后附上我的代码,一个是org版,一个mov版:

bootmov.asm:

code segment
start:
 mov ax,07c0h     ;init
 mov ds,ax      
 mov es,ax
 call dispstr
 jmp $       ;循环
dispstr:
 mov ax,msg      ;以下几行参见原书注释
 mov bp,ax
 mov cx,15
 mov ax,01301h
 mov bx,000ch
 mov dl,0
 int 10h
 ret
msg:
 db "Hello,OS world!"   ;所要打印字符串
 db 510-($-[start]) dup(0)
 dw 0AA55h
 code ends     ;编译结束
 end start

 

bootorg.asm

code segment
 org 07c00h
start:
 mov ax,cs     ;init
 mov ds,ax      
 mov es,ax
 call dispstr
 jmp $       ;循环
dispstr:
 mov ax,msg      ;以下几行参见原书注释
 mov bp,ax
 mov cx,15
 mov ax,01301h
 mov bx,000ch
 mov dl,0
 int 10h
 ret
msg:
 db "Hello,OS world!"   ;所要打印字符串
 db 510-($-[start]) dup(0)
 dw 0AA55h
 code ends     ;编译结束
 end start

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值