ATT汇编

前话

汇编不用多说,就是符号化了机器指令,是一种很低级(靠近硬件)的编程。很多人接触比较多的是 windows 下的 Intel 汇编,然而 unix/linux 下 or 使用 gcc 的话,用的是 ATT 汇编。(unix 最初是 AT&T 实验室中的 Ken Thompson 发明的。)

Intel 汇编和 ATT 汇编使用的指令基本一样,就是写法上有些差异,鉴于前者有很多人介绍,而后者相对比较少,故有了此篇文章。 (me 也曾经想在 linux 看下汇编的写法,然而搜到的基本都是 Intel 汇编,赶脚很失落,O__O"…)

ATT 汇编格式

ATT 汇编大体格式是: 指令 源操作数 目的操作数 ,比如将 10 移动到 eax 寄存器的写法: movl $10, %eax 。

  1. ATT 汇编的源操作数和目的操作数和 Intel 正好相反,也就是数据流向是从左到右;
  2. ATT 中立即数前需要加 $ 符号, 寄存器前加 % 符号;
  3. ATT 的指令加后缀 b 、 w、 l 、q 表明处理的数据长度,分别是字节、字(2B)、双字(4B)、四字(8B);
  4. ATT 以寄存器中的值为地址的内存单元的访问(间接寻址)是加上括号比如 (%eax),而非 Intel 的 [EAX] 。

ATT 常用指令

(1) 移动指令 movN src dst : movl $a, %ebx

(2) 运算指令 加 addN 、 减 subN 、按位与 andN 、按位异或 xorN src dst : xor %eax %eax (将 eax 值置为 0)

(3) 比较指令 cmpN src dst : cmp (%eax) $10

(4) 跳转指令 jmp、大于跳转 jg、小于跳转 jl 、大于等于跳转 jge、 jle、 je、 jne

(5) 函数调用 call 和返回 ret

ATT 汇编代码示例

(1) hello,world

上来先见识一下 hello,world 的写法:


   
   
   
  1. .data
  2. msg:
  3. .ascii "hello,world\0"
  4. .text
  5. .globl _main
  6. _main:
  7. # 函数调用的“开场白”
  8. pushl %ebp
  9. movl %esp, %ebp
  10. andl $-16, %esp
  11. # 调用 puts 函数
  12. pushl $msg
  13. call _puts
  14. # 设置返回值
  15. movl $0, %eax
  16. # 函数调用的“结束语”
  17. leave
  18. ret

上面 "hello,world" 字符串的输出是通过调用 c 的库函数 puts 实现的。 汇编上面的代码可以:$ gcc -o hello hello.s 。

(1) 在 linux 下汇编此程序如果说找不到 _start 那么将程序中的 _main 改成 _start 就好。

(2) 除了使用 gcc 命令之外,也可以先汇编 $ as -o hello.o hello.s 然后再链接 $ ld hello.o -o hello 生成可执行文件。(如果 windows 下说找不到 _puts 标识符,可以 $ld hello.o -lmsvcrt )。

程序解释:

(1) 实现 "hello,world" 打印输出的其实只有下面两行:


   
   
   
    • 14
      点赞
    • 37
      收藏
      觉得还不错? 一键收藏
    • 1
      评论

    “相关推荐”对你有帮助么?

    • 非常没帮助
    • 没帮助
    • 一般
    • 有帮助
    • 非常有帮助
    提交
    评论 1
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值