Linux 中的汇编语言(三)

3汇编程序指令(Assembler Directive

上面介绍的.section就是汇编程序指令的一种,GNU汇编程序提供了很多这样的指令(directiv),这种指令都是以句点(.)为开头,后跟指令名(小写字母),在此,我们只介绍在内核源代码中出现的几个指令(以arch/i386/kernel/head.S中的代码为例)。

 

1ascii "string"...

 

.ascii 表示零个或多个(用逗号隔开)字符串,并把每个字符串(结尾不自动加“0“字节)中的字符放在连续的地址单元。

 

还有一个与.ascii类似的.ascizz代表“0”,即每个字符串结尾自动加一个“0”字节,例如:

int_msg:

.asciz "Unknown interrupt/n"

 

2.byte 表达式

 

.byte表示零或多个表达式(用逗号隔开),每个表达式被放在下一个字节单元。

 

3.fill 表达式

 

形式:.fill repeat , size , value

 

其中,repeatsize value都是常量表达式。Fill的含义是反复拷贝size个字节。Repeat可以大于等于0size也可以大于等于0,但不能超过8,如果超过8,也只取8。把repeat个字节以8个为一组,每组的最高4个字节内容为0,最低4字节内容置为value

 

Size value为可选项。如果第二个逗号和value值不存在,则假定value0。如果第一个逗号和size不存在,则假定size1

 

例如,在Linux初始化的过程中,对全局描述符表GDT进行设置的最后一句为:

.fill NR_CPUS*4,8,0 /* space for TSS's and LDT's */

 

因为每个描述符正好占8个字节,因此,.fill给每个CPU留有存放4个描述符的位置。

 

4.globl symbol

 

.globl使得连接程序(ld)能够看到symbl。如果你的局部程序中定义了symbl,那么,与这个局部程序连接的其他局部程序也能存取symbl,例如:

.globl SYMBOL_NAME(idt)

.globl SYMBOL_NAME(gdt)

 

定义idtgdt为全局符号。

 

5quad bignums

 

.quad表示零个或多个bignums(用逗号分隔),对于每个bignum,其缺省值是8字节整数。如果bignum超过8字节,则打印一个警告信息;并只取bignum最低8字节。例如,对全局描述符表的填充就用到这个指令:

.quad 0x00cf9a000000ffff /* 0x10 kernel 4GB code at 0x00000000 */

.quad 0x00cf92000000ffff /* 0x18 kernel 4GB data at 0x00000000 */

.quad 0x00cffa000000ffff /* 0x23 user 4GB code at 0x00000000 */

.quad 0x00cff2000000ffff /* 0x2b user 4GB data at 0x00000000 */

 

6rept count

 

.rept指令与.endr指令之间的行重复count次,例如

.rept 3

.long 0

.endr

 

相当于

.long 0

.long 0

.long 0

 

7space size , fill

 

这个指令保留size个字节的空间,每个字节的值为fillsize fill都是常量表达式。

如果逗号和fill被省略,则假定fill0,例如在arch/i386/bootl/setup.S中有一句:

.space 1024

 

表示保留1024字节的空间,并且每个字节的值为0

 

8.word expressions

 

这个表达式表示任意一节中的一个或多个表达式(用逗号分开),表达式的值占两个字节,例如:

gdt_descr

.word GDT_ENTRIES*8-1

表示变量gdt_descr的置为GDT_ENTRIES*8-1

 

9.long expressions

这与.word类似

 

10.org new-lc , fill

 

把当前节的位置计数器提前到new-lcnew location counter)。new-lc或者是一个常量表达式,或者是一个与当前子节处于同一节的表达式。也就是说,你不能用.org横跨段:如果new-lc是个错误的值,则.org被忽略。.org只能增加位置计数器的值,或者让其保持不变;但绝不能用.org来让位置计数器倒退。

 

注意,位置计数器的起始值是相对于一个节的开始的,而不是子节的开始。当位置计数器被提升后,中间位置的字节被填充值fill(这也是一个常量表达式)。如果逗号和fill都省略,则fill的缺省值为0

例如:.org 0x2000

ENTRY(pg0)

 

表示把位置计数器置为0x2000,这个位置存放的就是临时页表pg0

你可能感兴趣的:(linux,汇编,String,user,语言)