Chinaunix首页 | 论坛 | 博客
  • 博客访问: 250427
  • 博文数量: 181
  • 博客积分: 215
  • 博客等级: 民兵
  • 技术积分: 313
  • 用 户 组: 普通用户
  • 注册时间: 2012-05-17 19:39
个人简介

王的男人

文章分类

全部博文(181)

文章存档

2016年(2)

2015年(35)

2014年(17)

2013年(84)

2012年(49)

我的朋友

分类: LINUX

2014-04-21 14:24:12

原文地址:linux汇编语言 作者:zhe_wang

一、Hello,World!
Linux 是一个运行在保护模式下的 32 位操作系统,采用 flat memory 模式,目前最常用到的是 ELF 格式的二进制代码。一个 ELF 格式的可执行程序通常划分为如下几个部分:.text、.data 和 .bss,其中 .text 是只读的代码段,.data 是可读可写的数据段,而 .bss 则是可读可写且没有初始化的数据段。代码段和数据段在 ELF 中统称为 section,根据实际需要你可以使用其它标准的 section,也可以添加自定义 section,但一个 ELF 可执行程序至少应该有一个 .text 部分。

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

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

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

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

    AT&T 格式Intel 格式
    addl $1, %eaxadd eax, 1
  4. 在 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
  5. 在 AT&T 汇编格式中,绝对转移和调用指令(jump/call)的操作数前要加上'*'作为前缀,而在 Intel 格式中则不需要。
  6. 远程转移指令和远程子调用指令的操作码,在 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
  7. 在 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
-------------------------------------------------------------------------------------------------
三、linux内核中ATT汇编实例分析。
 movl %eax,PT_EAX(%esp)  (#define PT_EAX 24)
  --------------->mov [esp+24] ,eax 
将eax寄存器中的值写入到内存地址(esp + 24)中。

参考资料:http://www.ibm.com/developerworks/cn/linux/l-assembly/
阅读(525) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

yzh071372014-09-14 14:52:54

楼主,请教一个问题
请问leal -1(%ebx), %eax是把ebx-1指向的内存里的值放进eax吗,根据效果来看的确是的?
那这句leal -4(%ebp), %eax为啥取的却是地址呢?
就是eax里存的是x 的地址
因为它后面用到了call scanf,所以肯定存的是地址