杂货边角(2):ATT和INTEL汇编语法

2023-10-12 22:32

本文主要是介绍杂货边角(2):ATT和INTEL汇编语法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

汇编存在多种形式,目前主流的有AT&T汇编和INTEL汇编,这两种形式极其容易混淆,其中AT&T汇编语法被Linux和GCC广泛支持,而INTEL则由Windows支持,故而对于长期涉及到两种操作系统编程的人而言,这两种汇编语法虽本质相同,但是语法形式的差异常常让人混淆。这里便介绍了两者的主要区别。

1. 赋值方向不同
INTEL汇编语法第一个操作数表示目的操作数,第二个才是源操作数,赋值方向为从右向左;
mov eax , ebx //eax = eax + ebx
AT&T汇编语法则反过来,第一个为源操作数,第二个为目的操作数,故而看着更舒服。
movl %ebx, %eax //eax = eax + ebx

2. 前缀修饰符不同
其实从上面已经可以看到,除了赋值方向不同,INTEL的寄存器似乎是直接存取的,而AT&T则需要加上“%”前缀。其实INTEL语法中寄存器和立即数都不需要前缀修饰,而AT&T则均需要修饰

###  INTEL  ###
mov eax, 1   //eax = 1,将立即数1赋值填充到eax寄存器中###  AT&T  ###
movl $1, %eax //寄存器前缀加"%", 立即数前缀加"$"

3. 后缀修饰符位置不同
AT&T
在汇编时经常会碰到mov, movlmovb等组合出现,很是让人费解,其实mov后接的后缀是反应当前操作式的操作数字长。
‘b’ : byte 一字节; ‘w’: word 两字节; ‘l’: long 四字节
当前计算机分为32位,64位,也存在着32位寄存器和64位寄存器的区别,而操作数字节数存在word\dword\long\ long long的区别,寄存器资源是很宝贵的,所以同一个寄存器可能高位存放着一个操作数a, 低位存放着另一个操作数b,所以在操作指令中明确指出当前操作数的字长是很必要的。

/*下面指令针对的是32位操作系统*/
1. movb  %bl, %al   //声明当前操作数为1字节长,则取ebx寄存器的低8位(1字节)作为操作数
2. movw  %bx, %ax   //声明操作数为2字节长,取ebx寄存器的低16位(2字节)作为操作数
3. movl  (%ebx), %eax  //声明操作数为4字节长,ebx寄存器的32位全部空间全取

所以如果在编写程序时,在程序中人工插入了汇编码,并且是按照32位的分布格式来设计代码的,则需要在使用GCC编译器显示申明按照32位ELF格式编辑-m32

涉及到多个操作数,则必然涉及到类型转换。如果两个操作数的字长不一样,显然此时用mov[b,w,l]是不够的,这时便需要使用扩展指令movs,后接bl\ bw\ wl三种合法扩展后缀中的一种
‘bl’ : 单字节->4字节 ; ‘bw’: 单字节->2字节; ‘wl’: 2字节->4字节
可以看到只存在低到高的扩展,不存在wb这种反向的缩减,因为寄存器存放时会自动截断。
应用扩展指令movs的例子如

movsbl  %al,  %ebx   //将eax寄存器的低8位(1字节)先扩展成4字节数,然后塞进ebx寄存器中

INTEL
INTEL则和AT&T不同的是,并不是把后缀符加在mov后面,除非是申明内存地址存取时,才有相对应的语法:byte ptr\ word ptr\ dword ptr

/*同样是针对32位操作系统,并和上面的汇编代码一一对应*/
1. mov  al,  bl
2. mov  ax,  bx
3. mov  eax,  dword ptr[ebx]  //INTEL语法中基地址是用[]包括的,外部才是偏移量或修饰符

还有一个后缀符号,用于跳转命令的方向修饰,如jmp,跳转需要给出跳转步长,和跳转方向,则存在如下

1.  jmp   10f   //向前forwad跳10步
2.  jmp    10b  //后退back 10步

4. 间接寻址语法
其实前面提到过,AT&T语法中采用()圈定基地址,而INTEL采用[]圈定基地址,所以直接给出两者例子的对比

AT&T:  movl  8(%ebx), %eaxINTEL:  mov   eax,  dword ptr[ebx+8]

而其实AT&T的寻址语法还是蛮有意思的,其间接寻址语法格式如下
偏移量M ( 基地址base,间隔步长step,步长数n ) = * (base+step * n + M)
使用案例如下

1. 0xfc(, %eax, 4)    =       *(eax*4 + 0xfc)
2. 8(%eax,%ebx,4)     =       *(eax + ebx*4 + 8)
3. 9(%eax, %ebx)      =       *(eax + ebx*1 + 9) //步长数如果省略,默认为1

INTEL的寻址语法则直接比较粗暴了,间接寻址语法格式如下
修饰符 [ 基地址base + 步长*步长数 + 偏移量]

5. AT&T指令集
INTEL语法的指令集合AT&T指令集基本相同,由于AT&T更好看点,所以下面便介绍AT&T的指令集。

常见操作指令
这里写图片描述

64位乘除操作指令
对于32位系统而言,32位寄存器内做加减运算倒是简单,但是如果做32位乘除很容易跳出了32位限制,所以需要用两个寄存器联合使用来保存乘除运算的操作数或结果。一般而言都是将64位数的高32位放在edx,低32位放在eax寄存器中。
这里写图片描述

比较指令
这里写图片描述

条件码寄存器相关指令
条件码寄存器存放着最近一次运算的属性,说明如下
1. CF: 进位标志,最高位产生了进位
2. OF: 溢出标志,补码溢出
3. ZF: 零标志,上次结果是否为0
4. SF: 符号标志, 上次结果符号位
这里写图片描述

跳转指令
这里写图片描述
这里写图片描述

这里写图片描述
至此,关于基本汇编的内容收集结束。

这篇关于杂货边角(2):ATT和INTEL汇编语法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/198891

相关文章

Java汇编源码如何查看环境搭建

《Java汇编源码如何查看环境搭建》:本文主要介绍如何在IntelliJIDEA开发环境中搭建字节码和汇编环境,以便更好地进行代码调优和JVM学习,首先,介绍了如何配置IntelliJIDEA以方... 目录一、简介二、在IDEA开发环境中搭建汇编环境2.1 在IDEA中搭建字节码查看环境2.1.1 搭建步

笔记整理—内核!启动!—kernel部分(2)从汇编阶段到start_kernel

kernel起始与ENTRY(stext),和uboot一样,都是从汇编阶段开始的,因为对于kernel而言,还没进行栈的维护,所以无法使用c语言。_HEAD定义了后面代码属于段名为.head .text的段。         内核起始部分代码被解压代码调用,前面关于uboot的文章中有提到过(eg:zImage)。uboot启动是无条件的,只要代码的位置对,上电就工作,kern

C++语法知识点合集:11.模板

文章目录 一、非类型模板参数1.非类型模板参数的基本形式2.指针作为非类型模板参数3.引用作为非类型模板参数4.非类型模板参数的限制和陷阱:5.几个问题 二、模板的特化1.概念2.函数模板特化3.类模板特化(1)全特化(2)偏特化(3)类模板特化应用示例 三、模板分离编译1.概念2.模板的分离编译 模版总结 一、非类型模板参数 模板参数分类类型形参与非类型形参 非类型模板

Java基础回顾系列-第一天-基本语法

基本语法 Java基础回顾系列-第一天-基本语法基础常识人机交互方式常用的DOS命令什么是计算机语言(编程语言) Java语言简介Java程序运行机制Java虚拟机(Java Virtual Machine)垃圾收集机制(Garbage Collection) Java语言的特点面向对象健壮性跨平台性 编写第一个Java程序什么是JDK, JRE下载及安装 JDK配置环境变量 pathHe

Hibernate框架中,使用JDBC语法

/*** 调用存储过程* * @param PRONAME* @return*/public CallableStatement citePro(final String PRONAME){Session session = getCurrentSession();CallableStatement pro = session.doReturningWork(new ReturningWork<C

ORACLE语法-包(package)、存储过程(procedure)、游标(cursor)以及java对Result结果集的处理

陈科肇 示例: 包规范 CREATE OR REPLACE PACKAGE PACK_WMS_YX IS-- Author : CKZ-- Created : 2015/8/28 9:52:29-- Purpose : 同步数据-- Public type declarations,游标 退休订单TYPE retCursor IS REF CURSOR;-- RETURN vi_co_co

ElasticSearch的DSL查询⑤(ES数据聚合、DSL语法数据聚合、RestClient数据聚合)

目录 一、数据聚合 1.1 DSL实现聚合 1.1.1 Bucket聚合  1.1.2 带条件聚合 1.1.3 Metric聚合 1.1.4 总结 2.1 RestClient实现聚合 2.1.1 Bucket聚合 2.1.2 带条件聚合 2.2.3 Metric聚合 一、数据聚合 聚合(aggregations)可以让我们极其方便的实现对数据的统计、分析、运算。例如:

react笔记 8-16 JSX语法 定义数据 数据绑定

1、jsx语法 和vue一样  只能有一个根标签 一行代码写法 return <div>hello world</div> 多行代码返回必须加括号 return (<div><div>hello world</div><div>aaaaaaa</div></div>) 2、定义数据 数据绑定 constructor(){super()this.state={na

汇编:嵌入式软件架构学习资源

成为嵌入式软件架构设计师需要掌握多方面的知识,包括嵌入式系统、实时操作系统、硬件接口、软件设计模式等。 以下是一些推荐的博客和网站,可以帮助你深入学习嵌入式软件架构设计: ### 1. **Embedded.com**    - **网址**: [Embedded.com](https://www.embedded.com/)    - **简介**: 这是一个专注于嵌入式系统设计的专业网

python基础语法十一-赋值、浅拷贝、深拷贝

书接上回: python基础语法一-基本数据类型 python基础语法二-多维数据类型 python基础语法三-类 python基础语法四-数据可视化 python基础语法五-函数 python基础语法六-正则匹配 python基础语法七-openpyxl操作Excel python基础语法八-异常 python基础语法九-多进程和多线程 python基础语法十-文件和目录操作