Blog
Blog copied to clipboard
aarch64体系结构与编程2--GNU AS汇编器介绍
Arm64的汇编器
- ARM公司官方的汇编器
- GNU AS汇编器:aarch64-linux-gnu-as
- gcc采用as作为其汇编器,所以汇编码是AT&T格式的
- AT&T格式:源自贝尔实验室,为开发UNIX系统而产生的汇编语法
- ARM格式:arm官方汇编语法
gas汇编器语法
- label: 任何以冒号结尾的标识符都被认为是一个标号
- 注释:
- “//” 表示注释
- “#”:在一行的开始,表示注释整行
- 指令,伪指令,寄存器,可以全部是大写或者小写,GNU风格默认是小写
- Symbol:代表它所在的地址, 也可以当作变量或者函数来使用
- 全局symbol,可以使用.global来声明
- 局部symbol,主要在局部范围内使用,开头以0-99直接的数字为标号名,通常和b指令结合使用
- f:指示编译器向前搜索
- b:指示编译器向后搜索
例如
.global my_memory_test
my_memory_test:
mov x1, 0x80000
mov x2, 0x200000
add x3, x1, 32
1:
ldr x4, [x1], #8
str x4, [x2], #8
cmp x1, x3
b.cc 1b
ret
汇编器常用伪指令
对齐伪指令
.align 对齐,填充数据来实现对齐。可以填充0或者使用nop指令。
- 告诉汇编程序, align后面的汇编必须从下一个能被2^n整除的地址开始分配
- ARM64系统中,第一个参数表示2^n大小。
数据定义伪指令
- .byte: 把8位数当成数据插入到汇编中
- .hword: 把16位数当成数据插入到汇编中
- .long 和 .int:把32位数当成数据插入到汇编中
- .quad: 把64位数当成数据插入到汇编中
- .float: 把浮点数当成数据插入到汇编中
- .ascii “string” -> 把string当作数据插入到汇编中,ascii伪操作定义的字符串需要自行添加结尾字符'\0'。
- .asciz “string” -> 类似ascii,在string后面插入一个结尾字符’\0’。
- .rept:重复定义, 比如重复3次
- .equ: 赋值操作
- .set : 赋值操作
比如.equ abcd, 0x45 //让abcd 等于 0x45
函数相关的伪操作
- .global:定义一个全局的符号
- .include: 引用头文件
- .if,.else, .endif 控制语句
if语句
- .ifdef symbol 判断symbol是否定义
- .ifndef symbol 判断symbol是否没有定义
- .ifc string1,string2 字符串string1和string2是否相等
- .ifeq expression 判断expression的值是否为0
- .ifeqs string1,string2 等同于.ifc
- .ifge expression 判断expression的值是否大于等于0
- .ifle expression 判断expression的值是否小于等于0
- .ifne expression 判断expression的值是否不为0
与段相关的伪操作
- .section:表示接下来的汇编会链接到哪个段里,例如代码段,数据段等
- 每一个段以段名为开始, 以下一个段名或者文件结尾为结束
- .section name, “flags” 后面可以添加flags,表示段的属性。属性如下
- .pushsection: 把下面的代码push到指定的section中
- .popsection: 结束push 成对使用,仅仅是把 pushsection和popsection的圈出来的代码 加入到指定的section中,其他代码还是在原来的section
宏
- .macro和.endm组成一个 宏
- .macro后面跟着的是宏的名称,在后面是宏的参数
- 在宏里使用参数,需要添加前缀”\”
.macro plus1 p, p1
// 定义了一个名为plus1的宏,有两个参数p,和p1。
// 在宏里使用参数需要前缀,“\p” 表示第一个参数, “\p1”表示第二个参数
- 宏参数定义的时候可以 设置一个初始化值
.macro reserve_str p1=0 p2
// 第一个参数p1有一个初始化的值,0。这时候你可以使用reserve_str a,b或者reserve_str ,b来调用这个宏
解决办法:
- 使用空格 或者使用 altmacro+&
- 使用 “()” 表示 用来指示 字符串什么时候结束
Arm64编译选项
- EB: 用于大端模式的CPU, -EL:用于小端模式的CPU
- mabi:指定ABI模式,ilp32用于ELF32,lp64用于ELF64,默认值为lp64
- mcpu=processor+extension:指定CPU型号,例如cortex-a72
- march=,用于指定支持的架构,例如armv8.2-a
- ARM64支持的extension,见第9.1.2章
特殊字符
- “//” 注释
- “#”:若在一行开始,表示注释。另外还可以表示立即数
- “#:lo12”:表示低12位 adrp x0, foo ldr x0, [x0, #:lo12:foo ]
Arm64特有的伪操作
- .bss: 切换到bss段
- .dword/.xword: 64位数据
- name .reg register_name: 为寄存器创建别名 foo .reg w0