您的位置:首页 > 运维架构 > Linux

Linux 汇编语言(GNU GAS汇编)区别

2014-01-13 08:31 246 查看
二、Linux 汇编语法格式

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

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

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

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

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

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

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

AT&T 格式Intel 格式
ljump $section, $offsetjmp far section:offset
lcall $section, $offsetcall far section:offset
与之相应的远程返回指令则为:

AT&T 格式Intel 格式
lret $stack_adjustret 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(%ebp), %eaxmov eax, [ebp - 4]
movl array(, %eax, 4), %eaxmov eax, [eax*4 + array]
movw array(%ebx, %eax, 4), %cxmov cx, [ebx + 4*eax + array]
movb $4, %fs:(%eax)mov fs:eax, 4
GNU ARM汇编伪操作(Directives) 命令集

1.符号定义伪操作

操作符      语法格式            说明

.equ       .equ symbol,expr    将symbol定义为expr

.set       .set symbol,expr    和equ相同(.set=.equ)

.equiv     .equiv symbol        将symbol定义为expr,若symbol已定义则出错

.global    .global symbol       将symbol定义为全局标号

.globl     .globl symbol        和.global相同(.globl=.global)

.extern    .extern symbol       声明symbol为一个外部变量

2.数据定义伪操作

.byte      .byte expr {,expr}…  
分配一段字节内存单元,并用expr初始化字节内存单元(8bit)

.hword     .bword expr {,expr}… 
分配一段半字内存单元,并用expr初始化半字内存单元 (16bit)

.short     .short expr {,expr}… 
同.hword(16bit)

.word      .word expr {,expr}…  
分配一段字内存单元,并用expr初始化字内存单元(32bit)

.int       .int expr {,expr}…   
同.word(32bit)

.long      .long expr {,expr}…  
同.word(32bit)

.ascii  .ascii expr{,expr}… 分配一段字符串内存单元,并用expr初始化字符串内存单元(非零结束符)

.asciz  .asciz expr{,expr}… 分配一段字符串内存单元,并用expr初始化字符串内存单元(零结束符)

.string    .string expr {,expr}…  
同.asciz(零结束符)

.quad      .qua expr {,expr}…   
分配一段双字内存单元,并用expr初始化双字内存单元

.octa      .octa expr{,expr}…   
分配一段四字内存单元,并用expr初始化四字内存单元

.float  .float expr{,expr}…   
分配一段字内存单元,并用32位IEEE单精度浮点数expr初始化内存单元

.single .single expr{,expr}…  同.float 

.double .double expr{,expr}…  分配一段双字内存单元,并用64位IEEE双精度浮点数expr初始化内存单元

.fill   .fill repeat{,size}{,value} 用size个字节value填充repeat次(size默认为1,value默认为0)

.zero   .zreo size                  
用0填充size个字节的内存单元

.space  .space size{,value}         
用value填充size个字节的内存单元(value默认为0)

.skip   .space size{,value}         
同.space

.ltorg  .ltorg                     
声明一个数据缓冲池(literal pool)

3.汇编与反汇编代码控制伪操作

.arm        .arm                   
定义一下代码使用ARM指令集编译

.code 32    .code 32               
作用同.arm

.thumb      .thumb                
定义一下代码使用Thumb指令集编译

.code 16    .code 16               
作用同.thumb

.section    .section expr          
定义域中包含的段。expr可以使.text,.data.,.bss

.text       .text {subsection}     
将定义符开始的代码编译到代码段或代码子段(subsection)

.data       .data {subsection}     
将定义符开始的代码编译到数据段或数据子段(subsection)

.bss        .bss {subsection}      
将变量存放到.bss段或.bss的子段(subsection)

.align   .align{alignment}{,fill}{,max}
通过用零或指定的数据进行填充来使当前位置与指定边界对齐

.balign  .balign{alignment}{,fill}{,max}
作用同.align

.org        .org offset{,expr}     
指定从当前地址加上offset开始存放代码,并且从当前地址到当前

                                   
地址加上offset之间的内存单元,用零或指定的数据进行填充

org=origin

其他汇编与反汇编

.end       .end       
标记汇编文件的结束行,即标记后的代码不做处理

.err       .err       
使编译结果产生错误报告

.eject     .eject     
在汇编符号列表文件中插入一分页符

.list      .list      
.产生汇编列表(从.list到.nolist)

.nolist    .nolist    
汇编列表结束处。再次使用.list产生汇编列表

.title     .title "title_name"  
使用heading作为标题(位于汇编列表文件中文件名下一行)

.sbttl     .sbttl "title_name"  
使用heading作为子标题(位于.title标题下一行)

.print     .print string        
打印输出信息到标准输出

4.预定义控制操作

.if                              条件判断语句

.else                            条件判断语句

.endif                           条件结束语句

.macro                           标识宏定义的开始

.endm                            标识宏定义的结束

.exitm     .exitm                中途跳转出宏

.include   .include "file_name"  包含文件标识    
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: