ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

AT&T汇编

2021-09-17 16:34:28  阅读:206  来源: 互联网

标签:汇编 movl eax 地址 寻址 寄存器 AT&T ebx


本文简单介绍AT&T汇编语言,基于学过X86汇编

1.语法格式

1.寄存器

引用寄存器要在寄存器号前加百分号%,如“movl %eax, %ebx

8个32-bit寄存器 %eax,%ebx,%ecx,%edx,%edi,%esi,%ebp,%esp

8个16-bit寄存器 它们事实上是上面8个32-bit寄存器的低16位:
%ax,%bx,%cx,%dx,%di,%si,%bp,%sp

8个8-bit寄存器  %ah,%al,%bh,%bl,%ch,%cl,%dh,%dl
它们事实上是寄存器%ax,%bx,%cx,%dx的高8位和低8位

6个段寄存器   %cs(code),%ds(data),%ss(stack), %es,%fs,%gs

3个控制寄存器 %cr0,%cr2,%cr3; 

6个debug寄存器  %db0,%db1,%db2,%db3,%db6,%db7;
 
2个测试寄存器  %tr6,%tr7; 

8个浮点寄存器栈 %st(0),%st(1),%st(2),%st(3),%st(4),%st(5),%st(6),%st(7)

寄存器功能

以E开头的寄存器为32位
EAX(累加器,是算术运算的主要寄存器)
EBX(基址寄存器,在内存中寻址时存放基址)
ECX(计数器)
EDX(数据寄存器)
ESI(源变址)
EDI(目标变址)
ESP(堆栈指针)
EBP(基址指针)
EIP(程序计数器,存储的是将要执行的下一条指令放在内存中的地址)
EFLAGS(保存的是根据运算得到的结果设置的条件码ZF,CF,SF,OF)

段寄存器:
CS:代码段寄存器
SS:堆栈段寄存器
DS:数据段寄存器
ES、FS、GS:附加数据段寄存器


2.指令的长度后缀
在指令后面加上后缀表示长度,根据操作的是1字节、2字节、4字节、8字节,分别对应后缀b, w, l, q

movq $1, %rax

3.操作数顺序
操作数排列是从源(左)到目的(右)

movl %eax(源), %ebx(目的)  (ebx) = (eax)

4.立即数
使用立即数,要在数前面加符号$

1:
movl $0x04, %ebx” 

2:
para = 0x04 
movl $para, %ebx

5.注释
在AT&T中,注释既可以使用" ;",也可以使用" ! "

6.符号常数
符号常数直接引用

 value: .long 0x12a3f2de 
    movl value , %ebx 

指令执行的结果是将常数0x12a3f2de装入寄存器ebx,
引用符号地址在符号前加符号$, 如“movl $value, % ebx”则是将符号value的地址装入寄存器ebx

7.调用和跳转指令
段内调用和跳转指令为"call",“ret"和"jmp”,段间调用和跳转指令为"lcall",“lret"和"ljmp”

段间调用和跳转指令的格式

lcall/ljmp $SECTION, $OFFSET

段间返回指令为

lret $STACK-ADJUST

jmp, jcc, call指令跳转
在这里插入图片描述
寄存器:如果想要跳到寄存器%rax内容对应的地址,不是写成jmpq %rax,而是写成*jmpq %rax

立即数:如上表所示,不用加*号

内存:如果想要跳转到%rip + 0x10对应的地址,不是写成jmpq 0x10(%rip),而是写成jmpq *0x10(%rip)

8.数据声明

格式:命令 数据类型

.ascii 文本字符串

.asciz 以空字符串结尾的文本字符串

.byte  字节值

.double       双精度浮点数

.float 单精度浮点数

.int    32位整数

.long 32位整数(同32)

.octa  16字节整数

.quad 8字节整数

.short 16位整数

.single        单精度浮点数(和.float同)

两个命令声明缓冲:
命令 描述
.comm        声明未初始化的数据的通用内存区域

.lcomm       声明未初始化的数据的本地通用内存区域

9.寻址方式

1.直接寻址
把某个地址上的值放到寄存器中
movl 0x8000, %eax  # 把地址0x8000上的值放到eax中

2. 间址寻址
把寄存器上的值所代表的地址所指向的值放到寄存器中
movl $0x8000, %ebx  
movl %ebx, %eax  # 间址寻址, 把地址0x8000(在寄存器ebx中)上的值放到eax中

3. 基址寻址
以寄存器里的数值作为基址,加上一个常数得到最终地址,把地址上的值放到寄存器中
movl $0x8000, %eax  
movl 4(%eax), %ebx  #基址寻址, 把地址0x8004(0x8000+4)上的值放到eax中

4. 变址寻址
以两个寄存器里的数值之和加上一个常数得到最终地址,把地址上的值放到寄存器中
movl $0x8000, %eax   
movl $0x4, %ebx   
movl (%eax,%ebx), %ecx   #变址寻址, 把地址0x8004(0x8000+4)上的值放到ecx中

movl  4(%eax,%ebx), %ecx   #变址寻址, 把地址0x8008(0x8000+4+4)上的值放到ecx中


5. 比例变址寻址
以一个寄存器里的数值加上另一个寄存器里的数字 乘以一个比例因子(1,2,4,8)再加上一个常数得到最终地址,把地址上的值放到寄存器中
movl $0x2000, %eax   
movl $0x2, %ebx   
movl (,%eax,4), %ecx   #比例变址寻址, 把地址0x8000(0x2000 *4)上的值放到ecx中

movl  6(,%eax,4), %ecx   #比例变址寻址, 把地址0x8006(0x2000 *4+6)上的值放到ecx中

movl  (%ebx,%eax,4), %ecx   #变址寻址, 把地址0x8002(0x2000*4+2)上的值放到ecx中

movl  6(%ebx,%eax,4), %ecx   #变址寻址, 把地址0x8008(0x2000*4+2+6)上的值放到ecx中

10.文件组成

.text:存放代码对应的指令 正文段

.bss:存放未初始化的全局和静态变量,在运行时该区域初始是全0

.rodata:存放只读数据和变量,例如字符串字面量

.data:存放余下的数据和变量,可读可写 数据段

.ascii:定义一个字符串并且用双引号包含

.byte: 定义一个字符用单引号

.org:定义当前的汇编的位置

伪操作符语句是汇编器使用的指示符,它通常并不会产生任何代码,它由伪操作码和0个或多个操作数组成。每个操作码都是由一个一个点字符’.'开始,表示编译过程中的位置计数器。其值是点符号出现机器指令第一个字节的地址。

11.编译

1)使用as命令对汇编文件进行汇编生成目标文件:as xxx.s -o xxx.o

2)使用ld命令对目标文件进行链接生成可执行文件:ld xxx.o -o xxx

注意,ld命令进行链接要求目标文件的.text段必须有一个入口点,ld默认认为_start标签对应的代码是入口点

12.操作码前缀
用于修饰随后的代码
在这里插入图片描述

Intel和AT&T汇编语法差异

1.前缀
Intel汇编寄存器和立即数无需前缀。后者寄存器前缀为%,立即数前缀为$

2.内存变量
Intel语法使用中括号[],后者使用小括号()

3.后缀
AT&T汇编指令有后缀(b,w,l,q),以表明数据类型(8位、16位等);Intel则根据寄存器自动识别

标签:汇编,movl,eax,地址,寻址,寄存器,AT&T,ebx
来源: https://blog.csdn.net/qq_53144843/article/details/120346586

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有