用户程序头

用户程序

用户程序,就是被编写用来解决特定问题的程序,由加载器调用。
在我们实际的开发中,加载器和用户程序通常都是由不同的厂商编写的。这样加载器一般都是直接拿到成品的用户程序,而在加载器不了解用户程序时,用户程序对于加载器来说就是一个黑盒子。但是,我们们都知道如果加载器要加载用户程序,那它就不能是一个纯的黑盒子,必须有一些可见的部分作为加载器的突破口。而这个突破口就是现在的用户程序头。
用户程序头相当于加载器和用户程序之间的协议,通过这个协议,不同的开发者就可以在两边互不了解的情况下,共同进行开发。

用户程序写入硬盘

dd of=[path]\boot.bin if=[path]\boot.vhd bs=512 count=1 seek=2

seek为定位表示从编号为2的扇区开始写入,写入磁盘的数量为count=1。

用户程序头

用户程序头并不是由编译器定义的,而是一个协议。其本质是一个放在程序开头的段
编写格式如下

SECTION header align=16 vstart=0

一个完美的用户程序头必须包含:程序的大小、应用程序的入口点、段重定位表项数、段重定位表

  1. 程序的大小。它的主要目的是,标明加载器要从硬盘中都多少字节。那如何计算程序的大小?我们可以直接计算。但这样太过复杂,在代码中,我们经常在最后定义一个标号(如program_end),因为这个标号是在程序的最后,因此它所代表的内容就是整个程序的大小,直接引用在开头就好。
    不过也要注意,如果program_end之前有划分段,且定义了vstart,就不能直接放一个program_end在最后了,program_end的值会受到vstart值的影响。这是就需要为program_end单独定义一个段,没有定义vstart的段。
section trail align=16			;注意,段16位对齐
program_end
  1. 程序的入口点。让加载器知道要都多少内容还不算完,我们还要让加载器知道程序的入口点在哪。我们确实可以默认让用户程序直接按顺序执行程序,但程序的真正顺序并不一定就是按照从上到下。这就需要,用户程序的开发者将入口点的位置表标出来。
    入口一般包含两个部分,段地址、偏移地址
code_entry   dw  start					;偏移地址
			  dd  section.code_1.start	;段起始地址
  1. 段重定位表项数。用户程序的大小是不确定的,用户程序的段数也不确定,这也需要在用户程序中直接标出。这样加载器就可以知道接下来要读的多少内容是段,可以防止多读以及少读。
    一般段重定位表项数,是通过段重定位表来计算的
realloc_table_len dw (table_end-table_begin)/4
  1. 段重定位表。字面意思,它指示的就是每个段在程序中的位置,以便加载器加载整个时,可以准确判定每一个段,并将其存放到正确的位置,也就是向每一个段基址,重新注入加载器计算好的物理地址。
    段重定位表设计如下
    code_1_segment  dd section.code_1.start 
    code_2_segment  dd section.code_2.start
    data_1_segment  dd section.data_1.start
    data_2_segment  dd section.data_2.start
    stack_segment   dd section.stack.start
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值