关于引导程序第一条指令为什么是org 07c00h,org到底是干嘛的

原文链接

在此对原作者表示感谢!

 费解了好久,一直不明白org是干嘛的。首先平时编程绝对不加org也能运行,为什么写引导区就要加上呢。其次,很多文章对此的解释是,org 07c00h会把程序加载到内存地址07c00(0000::7c00)处,但是它真能决定程序加载位置吗?

    先说第二个问题,在BIOS自检等一系列工作完成后,要开始引导了。计算机会将硬盘0面0道1扇区512字节加载到07c00h(0000::7c00)处。不管有没有org,都会加载到07c00处。org根本对程序加载位置没有任何影响,它只是伪指令,只在汇编器汇编阶段起作用,之后不翻译成机器指令。那既然程序已经加载到了07c00h处,为什么需要org??因为org是对汇编器的指示性语句。

我们假设程序代码如下(这程序过于简陋,只是为了示例!):

code segment  
  start:mov ax,offset msg  
    msg db "hello"  
code ends  
end start
<span style="color: rgb(85, 85, 85); font-family: 宋体, 'Arial Narrow', arial, serif; font-size: 13.63636302947998px; line-height: 25.454544067382813px; background-color: rgb(255, 255, 255);">如果程序这么写的话,那么汇编器默认在汇编时将mov ax,offset msg汇编成mov ax,0003h(这条语句3字节长,那么msg在段内偏移就是0003h了)。正常情况下,系统把这个程序会自动加载到自由内存区,并且是加载到某一段的0000h偏移处。比如在我的电脑上debug可以看到</span>
wKiom1OXAdmg1Pk6AADJfaL0Z1Y053.jpg

程序被加载到了075B段,偏移0000h处。

注意!我们的msg db "hello"被当作指令汇编了,显出来是push 6c65,其实push 6c65是我们的字符串!!

看看内存里的情况就知道了


wKioL1OXA2yCjE09AAEh6iB50PY400.jpg

看到了吧,

    好,回归正题,程序被加载到了075B段,偏移0000h,如果以后需要使用msg字符串,那么ax里面的偏移地址0003h是正确的,075B:0003处确实是我们的字符串。


    假设这个程序由于某种原因被系统强制加载到了075B:0100h,那么msg地址变成了075B:0103h,就是在0100h上加上自己的代码段段内偏移0003h。但是,mov ax,offset msg依然被汇编成了mov ax,0003h,以后要用字符串时,就去075B:0003处找,显然我们的程序字符串地址为075B:0103h,但是根据ax值,却要去075B:0003找字符串,肯定找不到。


    那么怎么办呢,org xxxx指令就派上用场了。告诉汇编器,把所有对内存的地址引用全都加上xxxx。

所以假设我们的程序被系统强制加载到了075B:0100h。

没关系,源代码改为:

code segment  
    org 0100h  
    start:mov ax,offset msg  
    msg db "hello"  
code ends  
end start

wKioL1OXByuQrZCaAAHoPbbQhPw673.jpg

  果然,内存引用地址从0003被加上0100,变成0103了。现在程序要去找msg,就用ax的值去075B:0103h找。而实际上,075B:0103h处正好是字符串hello。这样就找对了。

    从此我们可以看出,org对程序加载位置没有任何影响。他只是告诉汇编器,给内存引用全部加上一个值,这在程序被强制加载到非0000h偏移时很有用。

    回到第一个问题,为什么一般程序不加org也对,因为程序被默认加载到某个内存段内,偏移0000的位置,不加org,相当于所有内存引用都以自己段内的偏移为准(msg在自己的代码段偏移0003),那么某个变量或标号在自己代码段内的偏移就是在内存段内的偏移。


    所以,一般编程不加org,因为程序默认加载地址的偏移就是0000h,可写引导扇区时,程序会被加载到0000段,偏移7c00,偏移不是0000,所以用org让所有的内存引用全都加上7c00h。于是,在引导扇区程序里,我们开头会看到这么一句 org 7c00h,因为汇编里十六进制要以数字开头,所以应该这么写org 07c00h。


    至此,我想说的说完了,可能讲的有点乱,不过这问题实在是当初让我非常晕,在大多数材料不深究的情况下,我随便写写,为自己记下笔记,也希望能对一些同样迷惑的朋友有指导作用。

    欢迎指正!


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值