Linux内核中常用的汇编(2)

3 .汇编程序指令( Assembler Directive )

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

( 1 ) ascii "string"...

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

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

int_msg:

.asciz "Unknown interrupt\n"

( 2 ) .byte 表达式

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

( 3 ) .fill 表达式

形式: .fill repeat , size , value

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

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

例如,在 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)

定义 idt 和 gdt 为全局符号。

( 5 ) quad 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 */

( 6 ) rept count

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

.rept   3

.long   0

.endr

相当于

.long   0

.long   0

.long   0

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wwpjgz.html