这是一段i386的引导代码,无org
1 mov ax, cs 2 mov ds, ax 3 mov es, ax 4 mov ax, 0b800h 5 mov gs, ax 6 mov al, 65 7 8 call DispStr ; 调用显示字符串例程 9 jmp $ ; 无限循环10 DispStr:11 mov ax, BootMessage12 mov bp, ax ; ES:BP = 串地址13 mov cx, 16 ; CX = 串长度14 mov ax, 01301h ; AH = 13, AL = 01h15 mov bx, 000ch ; 页号为0(BH = 0) 黑底红字(BL = 0Ch,高亮)16 mov dl, 017 int 10h ; 10h 号中断18 ret 19 BootMessage: db "Hello, OS world!"20 times 510-($-$$) db 0 ; 填充剩下的空间,使生成的二进制代码恰好为512字节21 dw 0xaa55 ; 结束标志
bochs运行结果:
? ??? ??? ??? ?ߐn 2.40
Copyright (C) 1990-2000 Elpin Systems, Inc.All rights reserved.Licensed for use with bochs, courtesy of MandrakeSoft.For information on this or other VGA development products, contactElpin Systems at: (800) 723-9038 or www.elpin.comBochs BIOS - build: 11/11/12$Revision: 11545 $ $Date: 2012-11-11 09:11:17 +0100 (So, 11. Nov 2012) $Options: apmbios pcibios pnpbios eltorito rombios32Press F12 for boot menu.Booting from Floppy...bochs动态反汇编结果:
00007c00: ( ): mov ax, cs ; 8cc8
00007c02: ( ): mov ds, ax ; 8ed800007c04: ( ): mov es, ax ; 8ec000007c06: ( ): mov ax, 0xb800 ; b800b800007c09: ( ): mov gs, ax ; 8ee800007c0b: ( ): mov al, 0x41 ; b04100007c0d: ( ): call .+2 ; e8020000007c10: ( ): jmp .-2 ; ebfe00007c12: ( ): mov ax, 0x0025 ; b8250000007c15: ( ): mov bp, ax ; 89c500007c17: ( ): mov cx, 0x0010 ; b9100000007c1a: ( ): mov ax, 0x1301 ; b8011300007c1d: ( ): mov bx, 0x000c ; bb0c0000007c20: ( ): mov dl, 0x00 ; b20000007c22: ( ): int 0x10 ; cd1000007c24: ( ): ret ; c3bios读取引导扇区的内容,并将其加载到0x7c00处(此时包括数据段和代码段整体已经在0x7c00处了),并且跳到此处开始执行(ip = 0x7c00),因为程序部分指令是位置无关的,所以可以执行,但是当寻址BootMessage时,由反汇编结果可知,其地址为0x0025, 但是此时程序在0x7c00处,所以0x0025不可能有BootMessage,所以程序并不能正确打印结果.
在0x7c00处设置断点:<bochs:1> b 0x7c00
打印cs:cs:0x0000
下面加上org:
1 org 07c00h ; 告诉编译器程序加载到7c00处 2 mov ax, cs 3 mov ds, ax 4 mov es, ax 5 mov ax, 0b800h 6 mov gs, ax 7 mov al, 65 8 9 call DispStr ; 调用显示字符串例程10 jmp $ ; 无限循环11 DispStr:12 mov ax, BootMessage13 mov bp, ax ; ES:BP = 串地址14 mov cx, 16 ; CX = 串长度15 mov ax, 01301h ; AH = 13, AL = 01h16 mov bx, 000ch ; 页号为0(BH = 0) 黑底红字(BL = 0Ch,高亮)17 mov dl, 018 int 10h ; 10h 号中断19 ret 20 BootMessage: db "Hello, OS world!"21 times 510-($-$$) db 0 ; 填充剩下的空间,使生成的二进制代码恰好为512字节22 dw 0xaa55 ; 结束标志
bochs运行结果:
Hello, OS world!<90>n 2.40
Copyright (C) 1990-2000 Elpin Systems, Inc.All rights reserved.Licensed for use with bochs, courtesy of MandrakeSoft.For information on this or other VGA development products, contactElpin Systems at: (800) 723-9038 or www.elpin.comBochs BIOS - build: 11/11/12$Revision: 11545 $ $Date: 2012-11-11 09:11:17 +0100 (So, 11. Nov 2012) $Options: apmbios pcibios pnpbios eltorito rombios32Press F12 for boot menu.Booting from Floppy...
bochs动态反汇编结果:
00007c00: ( ): mov ax, cs ; 8cc8
00007c02: ( ): mov ds, ax ; 8ed800007c04: ( ): mov es, ax ; 8ec000007c06: ( ): mov ax, 0xb800 ; b800b800007c09: ( ): mov gs, ax ; 8ee800007c0b: ( ): mov al, 0x41 ; b04100007c0d: ( ): call .+2 ; e8020000007c10: ( ): jmp .-2 ; ebfe00007c12: ( ): mov ax, 0x7c25 ; b8257c00007c15: ( ): mov bp, ax ; 89c500007c17: ( ): mov cx, 0x0010 ; b9100000007c1a: ( ): mov ax, 0x1301 ; b8011300007c1d: ( ): mov bx, 0x000c ; bb0c0000007c20: ( ): mov dl, 0x00 ; b20000007c22: ( ): int 0x10 ; cd1000007c24: ( ): ret ; c300007c25: ( ): dec ax ; 48加上org后,BootMessage的地址为0x7c25,所以程序可以正确寻址BootMessage
在0x7c00处设置断点:<bochs:1> b 0x7c00
打印cs:cs:0x0000
单步执行的话,cs 仍然是0x0000
综上:org指令并不改变cs的值,org在链接时期的重定位阶段起作用,改变符号引用的位置.