回过头来看我们的Helloworld程序,在Makefile中-Ttext 0x7c00,链接地址为0x7c00,code标号的偏移地址为0x15,则链接后其地址为0x7c15, 其他函数调用此函数时,也就会调用地址0x7c15,这时jmpl $0, $code语句反汇编后为:
假如我们在Makefile中改为-Ttext 0x0,因为code标号的偏移地址为0x15,则链接后其地址为0x15,而code所在的实际内存地址为0x7c15,这时我们还想跳转到code的话可用这条语句jmpl $0x7c0, $code,跳到0x7c0:0x15即0x7c0<<4+0x15=0x7c15处,此时反汇编后为:
可以体会一下-Ttext作用同样是 $code,一个是0x7c15,一个是0x15
bootsect.S文件代码
.text
.globl start/*程序从start处开始运行*/
.code16
start:
jmpl $0, $code
msg:
.string "Hello world!"
code:
mov %cs,%ax
mov %ax,%ds
mov %ax,%es
mov %ax,%ss
mov $0x400,%sp
call DispStr/*调用显示字符串函数*/
loop0:/*无限循环*/
jmp loop0
DispStr:
mov $msg ,%ax
mov %ax ,%bp/*es:bp = 串地址*/
mov $12 ,%cx/*cs = 串长度*/
mov $0x1301,%ax/*ah=13是功能号表示显示字符串 ,al=01是显示输出方式*/
mov $0x000c,%bx/*bh=0是0页,bl=0ch高亮 黑底红字*/
mov $0 ,%dl/*0行0列*/
int $0x10
ret
Makfile文件
AS =as
LD =ld
LDFLAGS = --oformat binary -N -e start -Ttext 0x7c00
Image:myboot #head
dd bs=512 if=myboot of=Image count=1 conv=notrunc
sync
myboot:bootsect.s
$(AS) -o myboot.o -a bootsect.s
$(LD) $(LDFLAGS) -o myboot myboot.o
clean:
rm -f Image boot head *.o
下面是链接地址为0的代码:
.text
.globl start/*程序从start处开始运行*/
.code16
start:
jmpl $0x7c0, $code //-Ttext 0x7c00
msg:
.string "Hello world!"
code:
mov %cs,%ax
mov %ax,%ds
mov %ax,%es
mov %ax,%ss
mov $0x400,%sp
call DispStr/*调用显示字符串函数*/
loop0:/*无限循环*/
jmp loop0
DispStr:
mov $msg ,%ax
mov %ax ,%bp/*es:bp = 串地址*/
mov $12 ,%cx/*cs = 串长度*/
mov $0x1301,%ax/*ah=13是功能号表示显示字符串 ,al=01是显示输出方式*/
mov $0x000c,%bx/*bh=0是0页,bl=0ch高亮 黑底红字*/
mov $0 ,%dl/*0行0列*/
int $0x10
ret
.org 0x1fe, 0x90
.word 0xaa55
Makefile:
AS =as
LD =ld
LDFLAGS = --oformat binary -N -e start -Ttext 0x0
Image:myboot #head
dd bs=512 if=myboot of=Image count=1 conv=notrunc
sync
myboot:bootsect.s
$(AS) -o myboot.o -a bootsect.s
$(LD) $(LDFLAGS) -o myboot myboot.o
clean:
rm -f Image boot head *.o