从U盘启动的Hello world

我看的是于渊的《Orange's一个操作系统的实现》,有如下代码

org	07c00h			; 告诉编译器程序加载到7c00处
	mov	ax, cs
	mov	ds, ax
	mov	es, ax
	call	DispStr			; 调用显示字符串例程
	jmp	$			; 无限循环
DispStr:
	mov	ax, BootMessage
	mov	bp, ax			; ES:BP = 串地址
	mov	cx, 16			; CX = 串长度
	mov	ax, 01301h		; AH = 13,  AL = 01h
	mov	bx, 000ch		; 页号为0(BH = 0) 黑底红字(BL = 0Ch,高亮)
	mov	dl, 0
	int	10h			; 10h 号中断
	ret
BootMessage:		db	"Hello, OS world!"
times 	510-($-$$)	db	0	; 填充剩下的空间,使生成的二进制代码恰好为512字节
dw 	0xaa55				; 结束标志


 

 nasm编译后bin文件,在做成img文件,用vpc,bochs,vbox,vmware启动都是没问题的.

 现在想,如果能用U盘启动就好了,插上U盘,用bin文件写到U盘第一扇区,

 重启计算机,进入bios,设置U盘模式为HDD硬盘模式,再把首启动改成U盘,重启
结果发现.启动失败,是的他失败了,而os其他的几个例子也会失败.为什么呢?????
 
 开始以为是int中断的问题,改字符,改页号,改颜色,改模式....
 
第一种解决办法,是对比MBR,最后发现:
 软盘的es=0,ds=0,ss=0,cs=00,而硬盘加载时es=0,ds=0,ss=0,cs=7c0h.
 
 那么用上面的中断 ES:BP将访问不到0000:7c00处的字符串地址,显然只需要清零es就行了.

org	07c00h			; 告诉编译器程序加载到7c00处
	xor	ax, ax            ;>>>>>>>>>>>>>>>>>>>清零es
	mov	ds, ax
	mov	es, ax            ;>>>>>>>>>>>>>>>>>>>清零es	
         call	DispStr			; 调用显示字符串例程
	jmp	$			; 无限循环
DispStr:
	mov	ax, BootMessage
	mov	bp, ax			; ES:BP = 串地址
	mov	cx, 25			; CX = 串长度
	mov	ax, 01301h		; AH = 13,  AL = 01h
	mov	bx, 000ch		; 页号为0(BH = 0) 黑底红字(BL = 0Ch,高亮)
	mov	dl, 0
	int	10h			; 10h 号中断
	ret
BootMessage:		db	"The test is the best way."
times 	510-($-$$)	db	0	; 填充剩下的空间,使生成的二进制代码恰好为512字节
dw 	0xaa55				; 结束标志


第二种解决办法,是在考虑BootMessage的实际地址,最后发现:
 真实为es:bp=es:7c00+offset=es:org+offset
 
 那么修改方式也就出来了,就是去掉org 07c00h就行了.

	mov	ax, cs
	mov	ds, ax
	mov	es, ax
	call	DispStr			; 调用显示字符串例程
	jmp	$			; 无限循环
DispStr:
	mov	ax, BootMessage
	mov	bp, ax			; ES:BP = 串地址
	mov	cx, 25			; CX = 串长度
	mov	ax, 01301h		; AH = 13,  AL = 01h
	mov	bx, 000ch		; 页号为0(BH = 0) 黑底红字(BL = 0Ch,高亮)
	mov	dl, 0
	int	10h			; 10h 号中断
	ret
BootMessage:		db	"The test is the best way."
times 	510-($-$$)	db	0	; 填充剩下的空间,使生成的二进制代码恰好为512字节
dw 	0xaa55				; 结束标志



用nasm编译.两种方法都可以在U盘执行....

见下表

(在硬盘)	
第一种,保留org 7c00h,把es,ds清零	es:bp=	0:7c00+BootMessage	 "OK"
第二种,去掉org 7c00h,cs赋值给es,ds	es:bp=	07c0:BootMessage	"OK"	 
(在软盘)
第一种,保留org 7c00h,把es,ds清零	es:bp=	0:7c00+BootMessage	"OK"	;Orange用的方法
第二种,去掉org 7c00h,cs赋值给es,ds	es:bp=	0:BootMessage		"Error"	;这样,地址错


这四种结论 都经过实验,结论全正确

归根结底,就是对 ES:org+offset  位置的访问

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值