intel语AT&T语法
前缀
AT&T语法寄存器前要加%,立即数前要加$。intel语法的16进制数和2进制数后加'h'和'b'。16进制数第一个如果为字母,在需要加前缀0。
Intex Syntax
Intex Syntax
intel基自寄存器在[]里面,AT&T在()里面
Intex Syntax
AT&T语法%segreg:disp(base,index,scale)
index/scale/disp/segreg都是可选的,scale,如果没有选,如果选了index那么scale默认为1
segreg要看是在实模式还是保护模式。AT&T如果scale/disp是立即数,不加$前缀。
Intel Syntax
AT&T,b,w,l movb movw movl
Intel Syntax
对于大于5个参数的系统调用,参数存放在内存中,且%ebx指向内存地址,如果在栈中,参数反向入栈,结果是第一个参数在栈顶,%ebx指向栈顶。否则,将参数拷贝到分配的内存处,%ebx指向首地址。
Example:
(mmap being the example syscall). Using mmap() in C:
ASM Equivalent:
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执行。
GCC内嵌汇编
阅读(666) | 评论(0) | 转发(0) |
<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>
前缀
AT&T语法寄存器前要加%,立即数前要加$。intel语法的16进制数和2进制数后加'h'和'b'。16进制数第一个如果为字母,在需要加前缀0。
Intex Syntax
mov eax,1AT&T Syntax
mov ebx,0ffh
int 80h
movl $1,%eax指令的方向,intel从右往左,AT&T从左往右
movl $0xff,%ebx
int $0x80
Intex Syntax
instr dest,sourceAT&T Syntax
mov eax,[ecx]
instr source,dest内存操作
movl (%ecx),%eax
intel基自寄存器在[]里面,AT&T在()里面
Intex Syntax
mov eax,[ebx]AT&T Syntax
mov eax,[ebx+3]
movl (%ebx),%eaxintel语法segreg:[base+index*scale+disp]
movl 3(%ebx),%eax
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]AT&T Syntax
mov eax,[ebx+20h]
add eax,[ebx+ecx*2h
lea eax,[ebx+ecx]
sub eax,[ebx+ecx*4h-20h]
instr %segreg:disp(base,index,scale),foointel byte ptr,word ptr dword ptr
movl 0x20(%ebx),%eax
addl (%ebx,%ecx,0x2),%eax
leal (%ebx,%ecx),%eax
subl -0x20(%ebx,%ecx,0x4),%eax
AT&T,b,w,l movb movw movl
Intel Syntax
mov al,blAT&T Syntax
mov ax,bx
mov eax,ebx
mov eax, dword ptr [ebx]
movb %bl,%al对于小于6个参数的系统调用,参数传递顺序是%ebx,%ecx,%edx,%esi,%edi
movw %bx,%ax
movl %ebx,%eax
movl (%ebx),%eax
对于大于5个参数的系统调用,参数存放在内存中,且%ebx指向内存地址,如果在栈中,参数反向入栈,结果是第一个参数在栈顶,%ebx指向栈顶。否则,将参数拷贝到分配的内存处,%ebx指向首地址。
Example:
(mmap being the example syscall). Using mmap() in C:
#include <sys/types.h>Arrangement of mmap() args in memory:
#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);
}
%esp | %esp+4 | %esp+8 | %esp+12 | %esp+16 | %esp+20 |
00000000 | filelen | 00000001 | 00000001 | fd | 00000000 |
$ cat mmap.ssocket系统调用
.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
$
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 | |
Abbrev | Register |
a | %eax/%ax/%al |
b | %ebx/%bx/%bl |
c | %ecx/%cx/%cl |
d | %edx/%dx/%dl |
S | %esi/%si |
D | %edi/%di |
m | memory |
$ cat inline2.c"q"允许编译器选择a,b,c,d寄存器
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.
$
$ 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选项可以减小生成的程序大小
相关热门文章
给主人留下些什么吧!~~
评论热议