[AT&T汇编语言]第四讲 讨论hello.s文件
这一讲,我们再次看看hello.s文件。抛开伪指令,我们可以把hello.s文件分成五部分。第一部分:
BOOT_SECT = 0x07c0这算是gnu as 汇编语言中的宏定义、常数。学习过C语言,就知道这一句类似C语言中的
#define BOOT_SECT 0x07c0
第二部分:
程序代码:
_start: jmp $BOOT_SECT, $go go: mov %cs, %ax mov %ax, %ds mov %ax, %es因为x86架构在开机后,cs的值是0,ip的值是0x7c00。也就是说,当前的段地址是0,cs:ip指向的是0x7c00这个内存单元,起始就是jmp $BOOT_SECT, $go这一句。而为什么是这个地址,这是个历史问题,一两句话说不清楚,了解即可。
为了寻址方便,我们在链接目标文件时使用了-Ttext=0x0这个选项。这就是告诉连接器,所有的地址都是相对0这个地址偏移的。这样的好处是,我们可以把这段程序放在内存任意的地方。
jmp是跳转指令,是让CPU跳转到我们的要求地方。代码中,我们要求CPU跳转到0x07c0这个段中的go符号的地方。下面三行以mov开始的代码,起始是让ds和es指向和cs一样的段。
我们虽然跳转了,但这段代码在内存中的位置没有变。
第三部分:
程序代码:
mov $0x0003, %ax int $0x10 mov $0x1301, %ax mov $0x0007, %bx mov msg_len, %cx mov $0x0000, %dx mov $msg, %bp int $0x10 cpu_hlt: hlt jmp cpu_hlt这其实就是两次调用BIOS系统调用,以及循环让CPU停止,具体的以后再说。
第四部分:
msg: .ascii "Hello, world!" msg_len: .word .-msg这是在定义数据。对于CPU来说,它无法分区内存中的信息到底是代码还是数据,只有被cs:ip指向时才是代码,其他情况都是数据。
第五部分:
.org 510 .word 0xAA55这是启动扇区标志,以后再说。
对于hello.s文件我们仍然不做详细描述,因为完全讲清楚它,我们几乎是在讲述整个汇编语言。我们只需要直到的是,这将是我们很长一段时间里汇编编程的模板。每次学习新东西,都是修改第三部分和第四部分,若非必要其他部分我们是不做修改的。