linux下使用汇编语言

intel语AT&T语法
前缀
AT&T语法寄存器前要加%,立即数前要加$。intel语法的16进制数和2进制数后加'h'和'b'。16进制数第一个如果为字母,在需要加前缀0。
Intex Syntax
mov	eax,1
mov ebx,0ffh
int 80h
AT&T Syntax
movl	$1,%eax
movl $0xff,%ebx
int $0x80
指令的方向,intel从右往左,AT&T从左往右
Intex Syntax
instr	dest,source
mov eax,[ecx]
AT&T Syntax
instr 	source,dest
movl (%ecx),%eax
内存操作
intel基自寄存器在[]里面,AT&T在()里面
Intex Syntax
mov	eax,[ebx]
mov eax,[ebx+3]
AT&T Syntax
movl	(%ebx),%eax
movl 3(%ebx),%eax
intel语法segreg:[base+index*scale+disp]
AT&T语法%segreg:disp(base,index,scale)
index/scale/disp/segreg都是可选的,scale,如果没有选,如果选了index那么scale默认为1
segreg要看是在实模式还是保护模式。AT&T如果scale/disp是立即数,不加$前缀。
Intel Syntax
instr 	foo,segreg:[base+index*scale+disp]
mov eax,[ebx+20h]
add eax,[ebx+ecx*2h
lea eax,[ebx+ecx]
sub eax,[ebx+ecx*4h-20h]
AT&T Syntax
instr	%segreg:disp(base,index,scale),foo
movl 0x20(%ebx),%eax
addl (%ebx,%ecx,0x2),%eax
leal (%ebx,%ecx),%eax

subl -0x20(%ebx,%ecx,0x4),%eax
intel byte ptr,word ptr dword ptr
AT&T,b,w,l   movb movw movl
Intel Syntax
mov	al,bl
mov ax,bx
mov eax,ebx
mov eax, dword ptr [ebx]
AT&T Syntax
movb	%bl,%al
movw %bx,%ax
movl %ebx,%eax
movl (%ebx),%eax
对于小于6个参数的系统调用,参数传递顺序是%ebx,%ecx,%edx,%esi,%edi
对于大于5个参数的系统调用,参数存放在内存中,且%ebx指向内存地址,如果在栈中,参数反向入栈,结果是第一个参数在栈顶,%ebx指向栈顶。否则,将参数拷贝到分配的内存处,%ebx指向首地址。
Example:
(mmap being the example syscall). Using mmap() in C:
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>

#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
00000000filelen0000000100000001fd00000000
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系统调用
root@administrator-laptop:~# cat /usr/include/asm/unistd_32.h|grep socket
#define __NR_socketcall        102
socket只使用102这个系统调用号,放在%eax中,子函数号可以在/usr/include/linux/net.h中查到,放在%ebx中,参数指针放在%ecx中,通过$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
$

GCC内嵌汇编
	__asm__("<asm routine>" : output : input : modify);


#include <stdio.h>

int main(void) {
int foo=10,bar=15;

__asm__ __volatile__ ("addl %%ebxx,%%eax"
: "=eax"(foo) // ouput
: "eax"(foo), "ebx"(bar)// input
: "eax" // modify
);
printf("foo+bar=%d\n", foo);
return 0;
}
$
__volatile__防止汇编指令被删除。

Abbrev Table
AbbrevRegister
a%eax/%ax/%al
b%ebx/%bx/%bl
c%ecx/%cx/%cl
d%edx/%dx/%dl
S%esi/%si
D%edi/%di
mmemory

$ cat inline2.c
int main(void) {
long eax;
short bx;
char cl;

__asm__("nop;nop;nop"); // to separate inline asm from the rest of
// the code
__volatile__ __asm__("
test %0,%0
test %1,%1
test %2,%2"
: /* no outputs */
: "a"((long)eax), "b"((short)bx), "c"((char)cl)
);
__asm__("nop;nop;nop");
return 0;
}
$ gcc -o inline2 inline2.c
$ gdb ./inline2
GNU gdb 4.18
Copyright 1998 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i686-pc-linux-gnulibc1"...
(no debugging symbols found)...
(gdb) disassemble main
Dump of assembler code for function main:
... start: inline asm ...
0x8048427 : nop
0x8048428 : nop
0x8048429 : nop
0x804842a : mov 0xfffffffc(%ebp),%eax
0x804842d : mov 0xfffffffa(%ebp),%bx
0x8048431 : mov 0xfffffff9(%ebp),%cl
0x8048434 : test %eax,%eax
0x8048436 : test %bx,%bx
0x8048439 : test %cl,%cl
0x804843b : nop
0x804843c : nop
0x804843d : nop
... end: inline asm ...
End of assembler dump.
$
"q"允许编译器选择a,b,c,d寄存器
$ cat inline3.c
#include <stdio.h>

int main(void) {
long eax=1,ebx=2;

__asm__ __volatile__ ("add %0,%2"
: "=b"((long)ebx)
: "a"((long)eax), "q"(ebx)
: "2"
);
printf("ebx=%x\n", ebx);
return 0;
}
$

编译时加-s选项可以减小生成的程序大小


<script type=text/javascript charset=utf-8 src="http://static.bshare.cn/b/buttonLite.js#style=-1&uuid=&pophcol=3&lang=zh"></script> <script type=text/javascript charset=utf-8 src="http://static.bshare.cn/b/bshareC0.js"></script>
阅读(666) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~
评论热议
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值