绝大多数 Linux 程序员以前只接触过DOS/Windows 下的汇编语言,这些汇编代码都是 Intel 风格的。但在 Unix 和 Linux 系统中,更多采用的还是 AT&T 格式,两者在语法格式上有着很大的不同:

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

AT&T 格式

Intel 格式

pushl �x

push eax

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

AT&T 格式

Intel 格式

pushl $1

push 1

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

AT&T 格式

Intel 格式

addl $1, �x

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]

由于 Linux 工作在保护模式下,用的是 32 位线性地址,所以在计算地址时不用考虑段基址和偏移量,而是采用如下的地址计算方法:

disp + base + index * scale

下面是一些内存操作数的例子:

AT&T 格式

Intel 格式

movl -4(�p), �x

mov eax, [ebp - 4]

movl array(, �x, 4), �x

mov eax, [eax*4 + array]

movw array(�x, �x, 4), %cx

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

movb $4, %fs:(�x)

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, �x  # 参数三:字符串长度

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

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

movl $4, �x    # 系统调用号(sys_write)

int  $0x80       # 调用内核功能

# 退出程序

movl $0,�x     # 参数一:退出代码

movl $1,�x     # 系统调用号(sys_exit)

int  $0x80       # 调用内核功能

初次接触到 AT&T 格式的汇编代码时,很多程序员都认为太晦涩难懂了,没有关系,在 Linux 平台上你同样可以使用 Intel 格式来编写汇编程序:

例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         ; 调用内核功能

上面两个汇编程序采用的语法虽然完全不同,但功能却都是调用 Linux 内核提供的 sys_write 来显示一个字符串,然后再调用 sys_exit 退出程序。在 Linux 内核源文件 include/asm-i386/unistd.h 中,可以找到所有系统调用的定义。

ATamp;T汇编格式相关推荐

  1. 制度汇编格式怎么生成目录_来自世界500强企业的管理表格DOC格式 1900套

    4 4 月 19 日 周 五u 实战云课堂干货有营养 任正非对于人力资源的认识可谓一针见血:HR日常花时间最多的事务性工作,并不能发挥HR的核心价值,只是在浪费HR的时间和公司的资源. 这就是老板视角 ...

  2. 制度汇编格式怎么生成目录_规章制度编写规范

    1 规章制度编写规范 第一条 本规范适用于公司所有单体制度. 制度起草时须严 格遵循规范进行起草,公文印发时的制度附件也须符合本规范. 制度汇编或单行本的印刷版式. 打印设置. 装订要求须遵照 公司的 ...

  3. 制度汇编格式怎么生成目录_标准制度编写规范

    制度编写规范 第一条 本规范适用于中国 ***** 所有单体制度. 制度起草时须严 格遵循规范进行起草,公文印发时的制度附件也须符合本规范. 制度汇编或单行本的印刷版式. 打印设置. 装订要求须遵照中 ...

  4. 制度汇编格式怎么生成目录_(完整word版)标准制度编写规范

    制度编写规范 第一条 本规范适用于中国 ***** 所有单体制度. 制度起草时须严 格遵循规范进行起草,公文印发时的制度附件也须符合本规范. 制度汇编或单行本的印刷版式. 打印设置. 装订要求须遵照中 ...

  5. c语言栈指针移动原理,C指针原理(4)-ATamp;T汇编

    首先我们先用汇编编写一个helloworld,注意我们直接在汇编代码中调用C语言的printf函数将"hello,world\n" 输出在屏幕上. .section .data o ...

  6. 制度汇编格式怎么生成目录_内部市场化制度汇编目录1

    内部市场化制度汇编目录1 内部市内部市场场化制度化制度汇编汇编目目录录一.市一.市场场化制度化制度责责任人胡建成任人胡建成1.企业标准体系文件 企管部2.2012 年内部市场化实施方案 企管部3.20 ...

  7. linux ATT汇编 与 Intel汇编 语法格式对比

    由于绝大多数的国内程序员以前只接触过Intel格式的汇编语言,很少或几乎没有接触过AT&T汇编语言,虽然这些汇编代码都是Intel风格的.但在Unix和Linux系统中,更多采用的还是AT&a ...

  8. Intel格式和ATT格式汇编区别

    一.AT&T 格式Linux 汇编语法格式<?xml:namespace prefix = "o" /> 在 AT&T 汇编格式中,寄存器名要加上 '% ...

  9. 【汇编语言与计算机系统结构笔记06】地址计算指令,lea / leal,x86-32与x86-64下的swap对比,汇编的格式对比(Intel/Microsoft Differs from GAS)

    本次笔记内容: 07.寻址模式与数据传输指令等-2 文章目录 变址寻址 寻址模式实例 总结mov指令 地址计算指令 lea 整数计算指令 将leal指令用于计算 实例1 实例2 x86-32与x86- ...

最新文章

  1. C# 利用反射调用类下的方法
  2. 常见的html行级元素及语义,HTML入门之——结构,常用标签及其属性,再加上语义化...
  3. 实验楼 1. k-近邻算法实现手写数字识别系统--《机器学习实战 》
  4. 一起聊聊Microsoft.Extensions.DependencyInjection
  5. Bit.com BCH期权上线以来日交易量持续翻倍
  6. 钢铁雄心II(HOI2)作弊码合辑
  7. 为啥用计算机分析模拟,模拟电路的计算机分析与设计——Pspice程序应用
  8. matlab对一个数组进行补零,matlab 输出 整数 补0
  9. 74xx系列芯片类型及功能概览
  10. 安装windows系统到移动硬盘
  11. java 俄罗斯 id_Java ZoneId systemDefault()用法及代码示例
  12. python pandas的read_html方法爬取网页表格
  13. 文档扫描OCR识别_积累
  14. [HNOI2007]最小矩形覆盖(旋转卡壳)
  15. 【Gem5】有关gem5模拟器的资料导航
  16. Python多线程——线程同步
  17. NXP JN5169 UART 波特率设置
  18. LeetCode 力扣C++题解 575. 分糖果
  19. Python图像锐化及边缘检测(Roberts、Prewitt、Sobel、Lapllacian、Canny、LOG)
  20. 调研分析:全球与中国多媒体投影仪镜头市场现状及未来发展趋势

热门文章

  1. libtorch tensor的使用
  2. UML笔记一:UML概述三(UML构成、UML中的事物)
  3. 电子印章结构以及规范讲解
  4. 微软 Build 2016年开发者大会发布多项功能升级
  5. 外链应该这样发,网站排名速度提升十陪 1
  6. 请求跨域设置同时允许cookie跨域(携带cookie)
  7. 【妙python】按照元素长度排序列表
  8. java--for循环执行的顺序
  9. 网络电视(IPTV)系统解决方案
  10. rtl8812驱动分析(二)