Linux 环境下汇编语言

导读:
  Linux 汇编
  Linux 环境下汇编语言
  By Phillip
  翻译:Yijian
  介绍:
  Intel 和 AT&T的汇编语法格式
  在Intel的汇编语法格式里寄存器前缀,而 AT&T汇编语法格式寄存器则有 ‘%’ 前缀,立即数前面要有前缀’$’
  在Intel的汇编语法格式里十六进制和字节立即数风别用加’h’和’b’后缀。并且如果十六进制的第一个数字是字母的话,这个值就需要加一个前缀‘0’。
  例子:
  Intel格式
  mov eax,1
  mov ebx,0ffh
  int 80h AT&T格式
  movl $1,%eax
  movl $0xff,%ebx
  int $0x80
  操作数发方向
  AT&T 和 Intel 格式中的源操作数和目标操作数的位置正好相反。在 Intel 汇编格式中,目标操作数在源操作数的左边;而在 AT&T 汇编格式中,目标操作数在源操作数的右边,我们通常从左到右阅读,AT&T汇编格式的用起来比较自然,这可能是它的优点
  例子:
  Intex 格式
  指令 dest,source
  mov eax,[ecx] AT&T 格式
  指令 source,dest
  movl (%ecx),%eax
  内存操作
  内存操作Intel和AT&T也是不一样。在Intel汇编格式基寄存器都用’[‘和’]’关闭,而AT&T格式用’(‘和’)’
  例子:
  Intex 格式
  mov eax,[ebx]
  mov eax,[ebx+3] AT&T 格式
  movl (%ebx),%eax
  movl 3(%ebx),%eax
  系统调用
  1 参数小于6的系统调用
  对于所有的系统调用,寄存器 eax 中存放的是系统调用的功能号.如果系统调用的参数小于6个。按顺序存放在ebx,ecx,edx,esi,edi五个寄存器里。返回值存储在eax里
  系统调用的功能号在/usr/include/sys/syscall.h下面。
  例子:
  $ cat write.s
  .include "defines.h"
  .data
  hello:
  .string "hello world/n"
  .globl main
  main:
  movl $SYS_write,%eax
  movl $STDOUT,%ebx
  movl $hello,%ecx
  movl $12,%edx
  int $0x80
  ret
  2.系统调用的参数大与5
  功能号仍然放在eax.但是参数放在连续的内存里了,并且指向第一个参数的指针的值放到ebx寄存器里。
  如果你用堆栈的话,参数必须从最后一个到第一个一次push到堆栈里。堆栈的指针应该放到ebx里。
  例如:
  (mmap being the example syscall). Using mmap() in C:
  #include
  #include
  #include
  #include
  #include
  #define STDOUT 1
  void main(void) {
  char file[]="mmap.s";
  char *mappedptr;
  int fd,filelen;
  fd=fopen(file, O_RDONLY);
  filelen=lseek(fd,0,SEEK_END);
  mappedptr=mmap(NULL,filelen,PROT_READ,MAP_SHARED,fd,0);
  write(STDOUT, mappedptr, filelen);
  munmap(mappedptr, filelen);
  close(fd);
  }
  Arrangement of mmap() args in memory:
  %esp %esp+4 %esp+8 %esp+12 %esp+16 %esp+20
  00000000 filelen 00000001 00000001 fd 00000000
  ASM Equivalent:
  $ cat mmap.s
  .include "defines.h"
  .data
  file:
  .string "mmap.s"
  fd:
  .long 0
  filelen:
  .long 0
  mappedptr:
  .long 0
  .globl main
  main:
  push %ebp
  movl %esp,%ebp
  subl $24,%esp
  // open($file, $O_RDONLY);
  movl $fd,%ebx // save fd
  movl %eax,(%ebx)
  // lseek($fd,0,$SEEK_END);
  movl $filelen,%ebx // save file length
  movl %eax,(%ebx)
  xorl %edx,%edx
  // mmap(NULL,$filelen,PROT_READ,MAP_SHARED,$fd,0);
  movl %edx,(%esp)
  movl %eax,4(%esp) // file length still in %eax
  movl $PROT_READ,8(%esp)
  movl $MAP_SHARED,12(%esp)
  movl $fd,%ebx // load file descriptor
  movl (%ebx),%eax
  movl %eax,16(%esp)
  movl %edx,20(%esp)
  movl $SYS_mmap,%eax
  movl %esp,%ebx
  int $0x80
  movl $mappedptr,%ebx // save ptr
  movl %eax,(%ebx)
  
  // write($stdout, $mappedptr, $filelen);
  // munmap($mappedptr, $filelen);
  // close($fd);
  
  movl %ebp,%esp
  popl %ebp
  ret
  $
  Socket网络编程的系统调用
  Socket系统调用只有一个功能号放到eax里。Socket函数次功能号在/usr/include/linux/net.h里,并且放到ebx里。指向参数的指针放到ecx里。Socket的系统调用仍然是通过int $0x80执行
  $ cat socket.s
  .include "defines.h"
  .globl _start
  _start:
  pushl %ebp
  movl %esp,%ebp
  sub $12,%esp
  // socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
  movl $AF_INET,(%esp)
  movl $SOCK_STREAM,4(%esp)
  movl $IPPROTO_TCP,8(%esp)
  movl $SYS_socketcall,%eax
  movl $SYS_socketcall_socket,%ebx
  movl %esp,%ecx
  int $0x80
  movl $SYS_exit,%eax
  xorl %ebx,%ebx
  int $0x80
  movl %ebp,%esp
  popl %ebp
  ret
  $
  命令行参数
  在 Linux 操作系统中,当一个可执行程序通过命令行启动时,其所需的参数将被保存到栈中:首先是 argc,然后是指向各个命令行参数的指针数组 argv,最后是指向环境变量的指针数据 envp。在编写汇编语言程序时,很多时候需要对这些参数进行处理,下面的代码示范了如何在汇编代码中进行命令行参数的处理:
  例如:
  /* args.s */
  .text
  .globl _start
  _start:
  popl %ecx // argc
  lewp:
  popl %ecx // argv
  test %ecx,%ecx
  jz exit
  movl %ecx,%ebx
  xorl %edx,%edx
  strlen:
  movb (%ebx),%al
  inc %edx
  inc %ebx
  test %al,%al
  jnz strlen
  movb $10,-1(%ebx)
  // write(1,argv[i],strlen(argv[i]));
  movl $SYS_write,%eax
  movl $STDOUT,%ebx
  int $0x80
  jmp lewp
  exit:
  movl $SYS_exit,%eax
  xorl %ebx,%ebx
  int $0x80
  
  ret
  GCC 嵌套汇编
  GCC基本的嵌套汇编非常明了,基本的格式如下:
  __asm__("movl %esp,%eax");
  或者:
  __asm__("
  movl $1,%eax // SYS_exit
  xor %ebx,%ebx
  int $0x80
  ");
  
  Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1828117

本文转自
http://blog.csdn.net/loardo/archive/2007/10/16/1828117.aspx
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值