https://sourceware.org/binutils/docs-2.28/as/Pseudo-Ops.html
所有的汇编器指令的名字以.开始。在大多数目标上,名字是大小写不敏感的,通常使用小写。
本章讨论和目标机器配置无关的指令。一些机器配置提供额外的指令。
1 .abort
立即停止汇编,为了和其它汇编器兼容。
2 .align abs-expr, abs-expr, abs-expr
填充location counter到特定的存储边界。第一个表达式是对齐要求。
第二个表达式给出要填充的值,可省略,如果省略,填充0。然而,在一些系统上,如果section被标记为包含代码,而且填充被省略,那么空间将被填充no-op指令。
第三个表达式也是绝对值,也是可选的,如果有,给出了对齐可跳过的最大字节数。如果对齐跳过的字节数大于该值,则不去进行对齐。使用两个逗号,可以省略第二表达式,但是指定第三个表达式,如果你想填充no-op指令,这很有用。
对齐要求的方式随系统变化。
使用ELF的i386,第一个表达式是对齐要求的字节数。如.align 8,将location counter前进到下一个8的整数倍的地址,如果当前已经是8的整数倍,则没有变化。
i386使用a.out、arm系统,第一个参数表示小端为0的位数,如.align 3,表示对齐到8字节。
这种不一致,是由于GAS要仿效这些系统的原生汇编器。GAS也提供.balign和.p2align来保持所有架构的一致行为。
3 .altmacro
开启可选宏模式。
4 .ascii string ...
.ascii指令后面跟着逗号分隔的一个或多个字符串常量。它把每个字符串(不包括结尾\0)汇编入连续的地址。
5 .asciz string ...
类似.ascii,但是每个字符串以\0结尾。
6 .balign[wl] abs-expr, abs-expr, abs-expr
和.align类似,但是保持所有架构表现行为一致。第一个参数是对齐要求的字节数。.balignw和.balignl变种指定填充模式为双字节还是4字节。
7 .bundle_align_mode abs-expr
bundle指令是这样的特性:指令不能跨过对齐边界。边界之间的指令是一个整体。如果指令可能跨过边界,就填充no-op指令。abs-expr等于0关闭bundle特性。
8 .bundle_lock/.bundle_unlock
只能用在bundle模式开启时,将多个指令指定为一个整体,不能跨过对齐边界。
9 .byte expression ...
参数为一个或多个表达式,每个用逗号分开,每个表达式汇编进下一个字节。
10 CFI指令
call frame information指令。是编译器用来描述函数发生了什么的方式。可以被调试器用来呈现调用栈。被链接器合成错误表等。
11 .comm symbol, length
声明一个叫symbol的comm符号。链接时,common符号可能和其它目标文件的已定义的或common符号合并。如果没有任何定义,则分配length字节的未定义内存。length必须为绝对表达式。如果多个同名common符号的长度不同,则选择最大的。
对于ELF格式,有可选的第三个参数表示对齐要求。对齐要求必须是绝对值,且必须为2的次方。
12 .data subsection
告诉as,将接下来的语句汇编进data子section的结尾。如果没有指定subsection,则为缺省0。
13 .def name
开始定义符号name的调试信息,直到.endef指令结束。
14 .double flonums ...
跟一个或多个逗号分开的浮点数,将浮点数汇编进连续的地址。
15 .end
标记汇编文件的结束,as不处理.end指令后的任何内容。
16 .equ symbol, expression
设置符号的值,等价于.set指令。
17 .equiv symbol, expression
和.equ一样设置符号的值,但是当符号已定义时,它将报错。注意一个符号被引用,不影响它是否定义。
18 .eqv symbol, expression
像.equiv一样,但是不会立即计算表达式的值,只有在符号被使用时才会计算。
19 .err
打印一个错误信息,除非使用-Z选项,否则不会产生目标文件。
20 .error string
和.err类似,但是你可以指定显示什么错误。
21 .exitm
提早从当前宏定义退出。
22 .extern
和其它汇编器兼容,被忽略。as把所有的未定义符号当做external。
23 .fail expression
表达式大于等于500产生警告,否则产生错误。
24 .file
有两种版本的.file指令:DWARF2版本和缺省版本。
缺省版本:.file string。告诉as将开始新的逻辑文件。
DWARF2版本:.file fileno filename
25 .fill repeat, size, value
repeat, size和value是绝对值,重复填充repeat次size大小的数据。repeat可以为0或多次。size可以为0或更多,超过8被认为是8。重复的内容从一个8字节拿取,最高的4字节位0,最低的4字节从value拿。字节序按照汇编的目标机器的字节序。
size和value是可选的,默认value为0,size为1。
26 .float flonums
发射一个或多个浮点数到输出。和.single有同样的效果。浮点数的类型依赖于as的配置。
27 .func name[, label]
发射函数名调试信息,如果汇编调试没有开启,被忽略。
28 .global symbol, .globl symbol
使符号对ld可见。
29 .gnu_attribute tag, value
记录一个gnu目标属性。
30 .hidden names
这是ELF可见性指令中的一个,其它两个是.internal和.protected。
设置符号的可见性为hidden。
31 .hword expressions
期待0个或多个表达式,每次发射16位数字。某些架构等价于.short和.word。
32 .ident
对于ELF,发射一个comment到.comment section。
33 .if absolue expression
用于条件汇编。结束指令伪.endif,也可以有.else或.elseif指令。
下列变种也被支持。
.ifdef symbol。符号是否已定义。
.ifb text。操作数是否为空。
.ifc string1, string2。两个字符串相同。
.ifeq absolute expression,等于0。
.ifeqs string, string。和.ifc相同,但是字符串必须要使用双引号。
.ifge absolue expression,表达式大于等于0。
.ifgt
.ifle
.iflt
.ifnb text。非空。
.ifnc string, string。两个字符串不同。
.ifndef symbol / .ifnotdef symbol。符号未定义。
.ifne absolute expression。不等于0。等价于.if
.ifnes string, string。.ifeqs的反。
34 .incbin "file"[,skip[,count]]
将文件的内容包含到current location。可以使用-I控制搜索路径。文件名周围的引号是要求的。skip指示跳过文件开头skip个字节。count指示读取的最大字节数。用户需要自己处理对齐。
35 .include "file"
在你的源文件中包含其它支持文件。该文件的代码被汇编,好像跟着.include所处的位置。include结束后,继续汇编原始文件。可以使用-I控制搜索路径。
36 .int expressions
期待一个或多个逗号分隔的表达式,每个表达式发射一个数字。字节序为目标架构的字节序。
37 .internal names
ELF可见性指令之一。符号被认为是hidden,对其他模块不可见。
38 .irp symbol, value
计算一些列语句,将不同的值赋给符号。一系列语句以.irp指令开始,以.endr指令结束。一个例子说明:
1 2 3 | .irp param,1,2,3 move d\param,sp@- .endr |
等价于
1 2 3 | move d1,sp@- move d2,sp@- move d3,sp@- |
39 .irpc symbol,values...
和irp不同,按字符处理,如上一节的例子等价于 .irpc param,123
40 .lcomm symbol, length
为symbol保留length长度的字节作为local common。地址是在bss section分配的。
一些架构允许第三个参数表示对齐要求。
41 .line line-number
改变逻辑行,通常用于调试。
42 .linkonce [type]
标记当前section在链接时仅有一个拷贝。在书写本文档时,仅支持PE格式。
43 .list
listings缺省是关闭的,通过-a命令行选项打开。.list和.nolist指令配合,控制是否产生assembly listings。这两个指令维护内部counter(初始值为0),.list增加,.nolist减小。当counter大于0时,产生汇编listings。
44 .ln line-number
.ln是.line的别名。
45 .loc / .loc_mark_labels
DWARF2调试信息相关指令。
46 .local names
ELF目标可用。names是逗号分隔,使他们为本地符号,外部不可见。如果符号还不存在,将创建。
对于.lcomm指令不接受对齐参数的目标。使用.local配合.comm指令来定义对齐的本地公共数据。
47 .long expressions
和.int相同。
48 .macro
命令.macro和.endm允许你定义产生汇编输出的宏。需要一个例子:
1 2 3 4 5 6 | .macro sum from=0, to=5 .long \from .if \to-\from sum "(\from+1)",\to .endif .endm |
这样,SUM 0,5等价于与汇编输出:
1 2 3 4 5 6 | .long 0 .long 1 .long 2 .long 3 .long 4 .long 5 |
.macro macname
.macro macname macargs...
可以指定参数,参数用逗号和空格分开。参数名后面立即跟:req,表示参数必须指定非空的值。参数名后立即跟=deflt, 表示参数的默认值。最后一个参数立即跟:vararg,表示可变参数,该参数被赋剩下的所有参数。你不能定义两个同名宏,除非.purgem指令。
下面是一些例子:
.macro comm
.macro plus p, p1
.macro plus p p1
.macro m p1:req, p2=0, p3:vararg
调用宏,可以按位置指定参数,也可以通过关键字,如
sum 9, 17
sum to=17, from=9
注意某些特殊字符可能被当做参数名,如:
1 2 3 | .macro lable l \l: .endm |
这里不会替换,因为l:被当做标识符。
上述问题的处理方法是:
使用空白,如\l :
使用\()分割,如\l\():
.endm 标记宏结束。
.exitm 提早退出宏。
\@ TODO
LOCAL name[,...]
只有开启可选宏才可用,--alternate 或 .altmacro
49 .mri val
如果val是非0,开启MRI模式。如果是0,关闭MRI模式。
50 .noaltmacro
关闭可选宏模式。
51 .nolist
见.list
52 .octa bignums
bignums为逗号分开的一个或多个参数。每个参数,发射一个16位整数。
53 .offset loc
在absolute section中,设置location counter为loc。loc必须为绝对值表达式。当定义符号为绝对值时,这个语法很有用。不要和.org指令混淆。
54 .org new-lc, fill
将当前section的location counter前进到new-lc,new-lc或者是绝对表达式,或者是相同section的表达式。
.org指令只能增加不能后退location counter。
原始的偏移是相对于section的开始处,而不是子section的开始处。
前进时,内容被填充为fill参数指定的值,如果没有指定fill,则填充0。
55 .p2align[wl] abs-expr, abs-expr, abs-expr
填充location counter到指定的对齐边界,第一个参数为对齐的位数。第二个参数是填充的值。第三个参数是最多前进的字节数,如果可能超过,则不对齐。
w变种,按双字节填充。l变种,按4字节填充。
56 .popsection
这是ELF section stack维护指令之一。
将栈中一下一个section作为当前section,并将当前section弹出。
57 .previous
这是ELF section stack维护指令之一。
交换当前section和前一个使用的section。
58 .print string
打印字符串到标准输出,字符串要使用双引号括起来。
59 .protected names
ELF可见性指令之一。符号引用必须被解析为同component的定义。
60 .purgem name
undefine宏定义。后续使用时不会展开。
61 .pushsection name[, subsection] [, "flags[, @type[,argument]]]
ELF section statck维护指令之一。
将当前section(和subsection)放入secction stack的顶部。然后使用name和subsection指定的section替换当前section和子section。
62 .quad bignums
发射逗号分开的8字节整数。
63 .reloc offset, reloc_name[, expression]
在offset处产生值为expssion的reloc_name类型的重定向信息。如果offset是数字,则重定向产生在当前section。如果是offset是符号加偏移的表达式,则重定向产生在符号所在的section。如果给出表达式,表达式必须为符号加addend,或者是绝对值。注意不是所有的目标都支持addend。
64 .rept count
重复到.endr指令之间的指令count次。如
1 2 3 | .rept 3 .long 0 .endr |
65 .sbttl "subheading"
产生assembly listings时,使用subheading作为标题。
66 .scl class
设置符号的storage-class值。只可用在.def/.endef之间。
67 .section name
将接下来的代码汇编如叫name的section。
只有支持任意名section的目标才能支持该指令。a.out不支持该指令。
ELF版本
这是ELF section stack维护指令之一。.section指令的格式如下:
.section name[, "flags"[, @type[, flag_specific_arguments]]]
如果提供--sectname-subst命令行选项,名字参数可以包含替换序列,目前只支持%S,替换为当前section name。
flags是引号引起来的标志,有下列标志可结合。
a allocatable
e excluded from executable and shared library
w writeable
x executable
M mergeable
S contains zero terminated strings
G member of a section group
T thread-local-storage
? a member of the previously-current-section's group, if any
<number> 数字指定的ELF section header flag。
某些target有它自己的标志。
type参数可包含下列常量之一。
@progbits section包含数据。
@nobits section不包含数据,(例如只占空间)
@note section包含除了程序之外的事物使用的数据。
@init_array 包含一个指针数组,指向init函数。
@fini_array 包含指针数组,指向finish函数。
@preinit_array 包含指针数组,指向preinit函数。
@<number> 要设置的ELF section header's type的值。
一些target有自己的类型。
有些目标@字符是注释的开始,如ARM,使用其它字符,如ARM使用%。
如果flags包含M,则type必须指定,而且必须指定entsize。如
.section name, "flags"M, @type, entsize
如果包含M,但不包含S,则section必须包含固定大小的常量,entsize长。TODO
如果包含G,则type必须指定,而且额外的参数指定为GroupName。
.section name, "flags"G, @type, GroupName[, linkage]
77 .set symbol, expression
设置符号的值。
78 .short expression
和.word相同。
79 .single
和.float相同。
80 .size
设置符号的大小。
ELF Version:
.size name, expression
81 .skip size, fill
和.space相同。
82 .space size, fill
发射size个字节,每个字节位fill,如果没有fill,则fill为0。
83 .string "str"
发射1个或多个字符串,字符串用逗号隔开,到目标文件。字符串在目标文件中是0结尾的。
变种是.string8/16/32/64。每个字符串占这么多字节,空余的用0,并按照目标的字节序。
84 .struct expression
转到absolute section。
85 .subsection name
ELF section stack维护指令之一。
将当前子section替换为name。当前section不变。
86 .symver
绑定符号到特定的版本。只在ELF平台支持。
87 .text subsection
指示汇编器将接下来的语句汇编进.text section。
88 .title "heading"
在生成assembly listings时,使用heading作为标题。
89 .type
用来设置符号的类型。
ELF Version
.type name, type description
设置符号的类型为函数符号或目标符号。type description有5种不同的语法支持。
.type <name> STT_<TYPE_IN_UPPER_CASE>
.type <name>,#<type>
.type <name>,@<type>
.type <name>,%<type>
.type <name>,"<type>"
有些字符在一些架构上是注释字符。所以上述一些语法不能适用于所有的架构。第一种在所有的架构上都被GNU汇编器接受。
类型如下:
STT_FUNC/function
STT_GNU_IFUNC/gnu_indirect_funcion
STT_OBJECT/object
STT_TLS/tls_object,标记符号为thread-local data object。
STT_COMMON/common,标记符号为common data object。
STT_NOTYPE/notype
gnu_unique_object 全局唯一数据目标。
90 .version "string"
产生一个.note section,并将version信息放入其中。
91 .vtable_entry table, offset
找到或创建一个叫table的符号。为它创建一个VTABLE_ENTRY重定向条目,加数为offset。
92 .zero size
发射size字节个0。
93 .word expression
发射0个或多个表达式。大小和字节序依赖于目标。
94 .warning "string"
给出警告信息。
95 .weak names
设置逗号分开的names的weak属性。如果符号不存在,则创建他们。
96 .weakref alias target
创建一个target符号的别名。
https://stackoverflow.com/questions/24462106/what-do-the-cfi-directives-mean-and-some-more-questions