由于绝大多数的国内程序员以前只接触过Intel格式的汇编语言,很少或几乎没有接触过AT&T汇编语言,虽然这些汇编代码都是Intel风格的。但在Unix和Linux系统中,更多采用的还是AT&T格式,两者在语法格式上有着很大的不同,其实完全可以使用原来汇编的思路解决问题,只要掌握下面两者的不同:

  一、在AT&T汇编格式中,寄存器名要加上' %'作为前缀;而在Intel汇编格式中,寄存器名不需要加前缀。例如:

AT&T格式

Intel格式

pushl %eax

push eax

  二、在AT&T汇编格式中,用'$'前缀表示一个立即操作数;而在Intel汇编格式中,立即数的表示不用带任何前缀。例如:

AT&T格式

Intel格式

pushl $1

push 1

  三、AT&T和Intel格式中的源操作数和目标操作数的位置正好相反。在Intel汇编格式中,目标操作数在源操作数的左边;而在AT&T汇编格式中,目标操作数在源操作数的右边。例如:

AT&T格式

Intel格式

addl $1, %eax

add eax, 1

  四、在AT&T汇编格式中,操作数的字长由操作符的最后一个字母决定,后缀'b'、'w'、'l'分别表示操作数为字节(byte,8比特)、字(word,16比特)和长字(long,32比特);而在Intel汇编格式中,操作数的字长是用"byte ptr"和"word ptr"等前缀来表示的。例如:

AT&T格式

Intel格式

movb val, %al

mov al, byte ptr val

  五、在AT&T汇编格式中,绝对转移和调用指令(jump/call)的操作数前要加上'*'作为前缀,而在Intel格式中则不需要。

远程转移指令和远程子调用指令的操作码,在AT&T汇编格式中为"ljump"和"lcall",而在Intel汇编格式中则为"jmp far"和"call far",即:

AT&T格式

Intel格式

ljump $section, $offset

jmp far section:offset

lcall $section, $offset

call far section:offset

  与之相应的远程返回指令则为:

AT&T格式

Intel格式

lret $stack_adjust

ret far stack_adjust

  六、在AT&T汇编格式中,内存操作数的寻址方式是

section:disp(base, index, scale)

  而在Intel汇编格式中,内存操作数的寻址方式为:

section:[base + index*scale + disp]

  无论形式如何,都是实现如下的地址计算:(其中base和index必须是寄存器,disp和scale可以是常数)

disp + base + index * scale

  下面请看内存操作数的例子:

AT&T格式

Intel格式

movl -4(%ebp), %eax

mov eax, [ebp - 4]

movl array(, %eax, 4), %eax

mov eax, [eax*4 + array]

movw array(%ebx, %eax, 4), %cx

mov cx, [ebx + 4*eax + array]

movb $4, %fs:(%eax)

mov fs:eax, 4

  七、不同语法格式的Hello World!程序

  所有程序设计语言的第一个例子都是在屏幕上打印一个字符串"Hello World!",那我们也以这种方式来开始介绍Linux下的汇编语言程序设计。在Linux操作系统中,你有很多办法可以实现在屏幕上显示一个字符串,但最简洁的方式是使用Linux内核提供的系统调用。使用这种方法最大的好处是可以直接和操作系统的内核进行通讯,不需要链接诸如libc这样的函数库,也不需要使用ELF解释器,因而代码尺寸小且执行速度快。Linux是一个运行在保护模式下的32位操作系统,采用flat memory模式,目前最常用到的是ELF格式的二进制代码。一个ELF格式的可执行程序通常划分为如下几个部分:.text、.data和.bss,其中.text是只读的代码区,.data是可读可写的数据区,而.bss则是可读可写且没有初始化的数据区。代码区和数据区在ELF中统称为section,根据实际需要你可以使用其它标准的section,也可以添加自定义section,但一个ELF可执行程序至少应该有一个.text部分。下面给出我们的第一个汇编程序,用的是AT&T汇编语言格式:

  例1.AT&T格式

#hello.s

.data#数据段声明

msg : .string "Hello, world!//n" #要输出的字符串

len = . - msg#字串长度

.text#代码段声明

.global _start#指定入口函数

_start:#在屏幕上显示一个字符串

movl $len, %edx#参数三:字符串长度

movl $msg, %ecx#参数二:要显示的字符串

movl $1, %ebx#参数一:文件描述符(stdout)

movl $4, %eax#系统调用号(sys_write)

int$0x80#调用内核功能

#退出程序

movl $0,%ebx#参数一:退出代码

movl $1,%eax#系统调用号(sys_exit)

int$0x80#调用内核功能

  初次接触到AT&T格式的汇编代码时,很多程序员都认为太晦涩难懂了,没有关系,在Linux平台上你同样可以使用Intel格式来编写汇编程序,建议还是坚持一下,毕竟在linux下at&t才是主流的语言格式:

  例2.Intel格式

; hello.asm

section .data;数据段声明

msg db "Hello, world!", 0xA;要输出的字符串

len equ $ - msg;字串长度

section .text;代码段声明

global _start;指定入口函数

_start:;在屏幕上显示一个字符串

mov edx, len;参数三:字符串长度

mov ecx, msg;参数二:要显示的字符串

mov ebx, 1;参数一:文件描述符(stdout)

mov eax, 4;系统调用号(sys_write)

int 0x80;调用内核功能

;退出程序

mov ebx, 0;参数一:退出代码

mov eax, 1;系统调用号(sys_exit)

int 0x80;调用内核功能

  上面两个汇编程序采用的语法虽然完全不同。

  相同的是: 1、功能却都是调用Linux内核提供的sys_write来显示一个字符串;

        2、调用sys_exit退出程序。在Linux内核源文件/usr/include/asm/unistd.h中,可以找到所有系统调用的定义。

  不同的是: 1、程序注释AT&T使用#开始注释,Intel使用;开始注释;

        2、AT&T段的声明直接使用.data和.text即可,Inter使用section .data和section .text;

Linux下AT&T汇编语法格式与Intel汇编语法格式异同的更多相关文章

  1. Linux下objdump查看C程序编译后的汇编代码

    http://m.blog.csdn.net/article/details?id=47747047 Uboot中start.S源码的指令级的详尽解析 http://www.crifan.com/fi ...

  2. LINUX下文件编译

    body, table{font-family: 微软雅黑} table{border-collapse: collapse; border: solid gray; border-width: 2p ...

  3. Linux下怎样搜索文件

    使用linux系统难免会忘记文件所在的位置,可以使用以下命令对系统中的文件进行搜索.搜索文件的命令为”find“:”locate“:”whereis“:”which“:”type“   方法/步骤   ...

  4. Linux下搜索文件

    使用linux系统难免会忘记文件所在的位置,可以使用以下命令对系统中的文件进行搜索.搜索文件的命令为"find":"locate":"whereis& ...

  5. [C/C++]linux下c-c++语法知识点归纳和总结

    1.c/c++申请动态内存 在c++中,申请动态内存是使用new和delete,这两个关键字实际上是运算符,并不是函数. 而在c中,申请动态内存则是使用malloc和free,这两个函数是c的标准库函 ...

  6. 位图文件(BMP)格式以及Linux下C程序实现(转)

    源:位图文件(BMP)格式以及Linux下C程序实现 说到图片,位图(Bitmap)当然是最简单的,它是Windows显示图片的基本格式,其文件扩展名为*.BMP.由于没有经过任何的压缩,故BMP图 ...

  7. linux下64位汇编的系统调用(5)

    看到这里大家都基本知道了如何进行linux下的汇编系统调用:不过有些童鞋可能会问:那些C库中函数里为我们解决的额外汇编代码你是怎么知道的? 好吧,我承认:我是通过逆向知道的,这貌似有点犯规的嫌疑- 比 ...

  8. linux下64位汇编的系统调用(1)

    现在基本上系统都是64位了,而64位系统下的汇编和32位有了较大的变化,无论是系统调用的接口还是C标准库的接口都和32位汇编有所不同:下面简单谈一下在64位linux下如何利用汇编直接调用系统调用. ...

  9. 【转】Linux下的文本dos格式转Unix格式,去除^M符号

    原文网址:http://blog.csdn.net/kobejayandy/article/details/13291525 问:我在Windows中通过FTP传一个文本文件到Linux中,但是打开文 ...

随机推荐

  1. MATLAB——解数独

    数独 数独是一种逻辑游戏,玩家需要根据9x9盘面的已知数字,推理出剩余所有空格的数字,并满足每一行.每一列和每个粗线宫(3x3)内均含1~9,不重复. MATLAB中有关函数 M = dlmread( ...

  2. k8s集群介绍

    Kubernetes集群组件 一个典型的Kubernetes集群由多个工作节点和一个集群控制节点,以及一个集群状态存储系统etcd组成.其中Master节点负责整个集群管理工作,为集群提供管理接口,并 ...

  3. vue 实现走马灯效果

    Part.1  问题 在写一个H5页面时遇到一个需求,头部公告需要滚动变换,需要实现一个走马灯效果 Part.2  实现 我的做法:利用 定时器 + CSS3 变换公告数组的顺序 从而实现走马灯效果 ...

  4. 三、绘图和可视化之matplotlib

    #matplotlib简单绘图之plot import matplotlib.pyplot as plt a=[1,2,3] b=[10,2,30] plt.plot(a)#纵坐标为a的值,横坐标为a ...

  5. UIScreen, UIWindow

    模仿书上或网上的例子,每次最开始就是 在 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions: ...

  6. http post get 同步异步

    下面首先介绍一下一些基本的概念---同步请求,异步请求,GET请求,POST请求. 1.同步请求从因特网请求数据,一旦发送同步请求,程序将停止用户交互,直至服务器返回数据完成,才可以进行下一步操作.也 ...

  7. Sass基本数据类型和各类型的原生方法

    数据类型: 数字:1,2,3,11,10px (可以带单位) 字符串:"asd",'asd',asd (有引号和无引号都是字符串类型) 如 $name : zhang san ; ...

  8. [LUOGU] P2759 奇怪的函数

    题目描述 使得 x^x x x 达到或超过 n 位数字的最小正整数 x 是多少? 输入输出格式 输入格式: 一个正整数 n 输出格式: 使得 x^xx x 达到 n 位数字的最小正整数 x 输入输出样 ...

  9. Windows环境下python3.7版本怎么安装pygame

    访问此网址 下载对应Python版本的pygame,如下图: 下载完成后,会有一个whl后缀的文件. 将此文件复制到Python根目录下的scripts目录下,打开cmd, 切换到scripts目录下 ...

  10. Codeforces Round #439 (Div. 2) C. The Intriguing Obsession

    C. The Intriguing Obsession 题目链接http://codeforces.com/contest/869/problem/C 解题心得:     1.由于题目中限制了两个相同 ...