简介
AT&T 汇编语法,通常称为 GAS 语法(GNU as汇编器的语法, GAS=GNU Assembler)。
相对 ARM汇编指令, AT&T 汇编语法的不同处
1. 指令的长度后缀
AT&T语法要求在指令后面加上后缀表示长度,根据操作的是1字节、2字节、4字节、8字节,分别对应后缀b, w, l, q。
注:
如果不加后缀,默认是 w 。
| 字节(B) | 后缀字母 | 注释 | 
|---|---|---|
| 1 | b | BYTE | 
| 2 | w | WORD | 
| 4 | l | LONG | 
| 8 | q | QUADWORD | 
例如:
movq $1, %rax。2. 跳转 和 函数调用 指令的语法
在 AT&T 汇编语法中,跳转、函数调用指令(jmp, jcc, call等)会涉及一些关于 寄存器Register、立即数Immediate、内存Memory的特殊使用方法,如下表所示:

上表给出了,如下所示:
- 寄存器 Register
 寄存器语法:
 例如:如果想要跳到寄存器*%寄存器%rax内容对应的地址,不是写成jmpq %rax,而是写成jmpq *%rax
- 立即数 Immediate
 立即数语法:
 如上表所示,不用加*号%立即数
- 内存 Memory
 内存语法:
 如果想要跳转到 %rip + 0x10 对应的地址,不是写成 jmpq 0x10(%rip) ,而是写成:*偏移量(%内存地址)jmpq *0x10(%rip)
3. 指令寄存器相对寻址 (%rip-relative)
在x86_64汇编中,我们可以使用 指令寄存器 相对寻址 这种寻址方式来定位全局变量和函数。
例如:C代码中有一个全局变量a,我们可以使用a(%rip)来定位到该变量,而不是使用a来定位。
使用这种寻址方式能帮助我们编写出 position-independent code (PIC) 的代码,进而获取 position-independent executables (PIEs) 的执行文件。
关于PIC和PIE的概念,涉及程序链接的细节,这里暂时不讲。
注意:汇编器在解析汇编代码时,不是将a(%rip)中的a解析成a的地址,而是会将a解析成变量a的地址和当前%rip的偏移,这也是为什么这种语法寻址a可行的原因。
4. 一个AT&T汇编文件代码分为哪些部分
一个按AT&T语法写的汇编文件分为多个section,在 文档 中有说明,这些section包括:
- .text
 代码段,该段包含可执行指令;
- .rodata
 只读数据段,用来存放只读数据。
 例如:字符串字面量(String Literal)。
- .data
 存放已初始化的全局变量和静态变量;
 存放可读写的数据;
- .bss
 未初始化的全局变量和静态变量,在运行时该区域初始是全0。
 .bss区域也可以用.comm/.lcomm和声明(https://sourceware.org/binutils/docs/as/bss.html#bss)
下面是一个C语言程序的内存布局,和汇编代码有一定的对应关系。

5. 如何编译和运行AT&T汇编代码
使用as命令对汇编文件进行汇编生成目标文件:
as xxx.s -o xxx.o然后使用ld命令对目标文件进行链接生成可执行文件:
ld xxx.o -o xxx注意:
ld命令进行链接要求目标文件的.text段必须有一个入口点,ld默认认为_start标签对应的代码是入口点。
例如下面的汇编代码:
.section .data
output:
    .string "Hello\n"
.text
.globl _start
_start:
    movq $1, %rax
    movq %rax, %rsp # stack alignment
    movq $1, %rdi
    movq $output, %rsi
    movq $6, %rdx
    syscall
    movq $60, %rax
    xor %rdi, %rdi
    syscall上面的汇编代码可以正常汇编和链接,但是,如果将代码中的_start标签去掉,或者改成其他名称,在执行ld命令之后就会报告一个警告信息:
ld: warning: cannot find entry symbol _start; defaulting to 00000000004000b0ld会默认给我们找一个入口点,有可能这个默认入口点是错误的,这样就会导致运行可执行文件出现错误。
原文链接:
https://blog.csdn.net/qq_29328443/article/details/107242121
状态:已核对
 我的书签
 我的书签
                                 添加书签
 添加书签 移除书签
 移除书签