FreeBSD fb7.arraynetworks.com.cn 7.0-RELEASE FreeBSD 7.0-RELEASE #0: Sun Feb 24 10:35:36 UTC 2008 [email protected]:/usr/obj/usr/src/sys/GENERIC amd64
NASM version 2.10.07 compiled on Apr 11 2013
- section .data
- message:
- db 'hello, world!', 0
- section .text
- global _start
- _start:
- mov rax, 4
- mov rdi, 1
- mov rsi, message
- mov rdx, 13
- syscall
- mov rax, 1
- xor rdi, rdi
- syscall
rax传递的是调用的syscall id
rdi第一个参数,fd
rsi第二个参数,字符串
rdx第三个参数,字符串长度。
这个是x86-64的约定,参数依次为RDI, RSI, RDX, RCX, R8, R9.如果再有就需要用栈了。
写一个C代码,反汇编看看也能得到上面的结论。
- long add(long a, int b, int c, int d, int e, int f, int g, int h, int i, int j, long k){
- long x = a + b + c + d + e + f + g;
- x = x + g + h + i +j + k;
- return x;
- }
- int main(){
- long x = add(0xfffffffff2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12);
- return 0x11;
- }
反汇编会得到如下的结果
- (gdb) disassemble main
- Dump of assembler code for function main:
- 0x0000000000400600
: push rbp - 0x0000000000400601
: mov rbp,rsp - 0x0000000000400604
: sub rsp,0x40 - 0x0000000000400608
: mov esi,0x8 - 0x000000000040060d
: mov edi,0x400700 - 0x0000000000400612
: mov eax,0x0 - 0x0000000000400617
: call 0x40042c - 0x000000000040061c
: mov DWORD PTR [rsp+32],0xc - 0x0000000000400625
: mov DWORD PTR [rsp+24],0xb - 0x000000000040062d
: mov DWORD PTR [rsp+16],0xa - 0x0000000000400635
: mov DWORD PTR [rsp+8],0x9 - 0x000000000040063d
: mov DWORD PTR [rsp],0x8 - 0x0000000000400644
: mov r9d,0x7 - 0x000000000040064a
: mov r8d,0x6 - 0x0000000000400650
: mov ecx,0x5 - 0x0000000000400655
: mov edx,0x4 - 0x000000000040065a
: mov esi,0x3 <----32 bit - 0x000000000040065f
: mov rdi,0xfffffffff2 <----64bit register - 0x0000000000400669
: call 0x400570 - 0x000000000040066e
: mov DWORD PTR [rbp-8],rax - 0x0000000000400672
: mov eax,0x11
另外一个需要注意的问题是,x86-64上,栈是16字节对齐的,比如如果没有参数需要从栈上传递的话,尽管返回指令压栈只占用8个字节,
但实际上,也会占用16个字节,比如下面的C代码
- long add(long a, int b, int c){
- long x = a + b + c;
- return x;
- }
- void print(){
- }
- int main(){
- long x = add(0xfffffffff2, 3, 4);
- print();
- return 0x11;
- }
- (gdb) disassemble main
- Dump of assembler code for function main:
- 0x0000000000400570
: push rbp - 0x0000000000400571
: mov rbp,rsp - 0x0000000000400574
: sub rsp,0x10 - 0x0000000000400578
: mov edx,0x4 - 0x000000000040057d
: mov esi,0x3 - 0x0000000000400582
: mov rdi,0xfffffffff2 - 0x000000000040058c
: call 0x400530 - 0x0000000000400591
: mov DWORD PTR [rbp-8],rax - 0x0000000000400595
: mov eax,0x0 - 0x000000000040059a
: call 0x400560 - 0x000000000040059f
: mov eax,0x11 - 0x00000000004005a4
: leave - 0x00000000004005a5
: ret - 0x00000000004005a6
: nop - 0x00000000004005a7
: nop - 0x00000000004005a8
: nop - 0x00000000004005a9
: nop - 0x00000000004005aa
: nop - 0x00000000004005ab
: nop - 0x00000000004005ac
: nop - 0x00000000004005ad
: nop - 0x00000000004005ae
: nop - 0x00000000004005af
: nop
- 0x000000000040058c in main ()
- (gdb) info reg rsp
- rsp 0x7fffffffeb00 0x7fffffffeb00
- (gdb) nexti
- Breakpoint 2, 0x0000000000400534 in add ()
- (gdb) info reg rsp
- rsp 0x7fffffffeaf0 0x7fffffffeaf0
- (gdb) x /3xg 0x7fffffffeaf0
- 0x7fffffffeaf0: 0x00007fffffffeb10 0x0000000000400591
- 0x7fffffffeb00: 0x0000000000000001
- (gdb)
愿意的话可以自己试一下另外一中情况,比如:
- long add(long a, int b, int c, int d, int e, int f, int g){
- long x = a + b + c + d + e + f + g;
- return x;
- }
- int main(){
- long x = add(0xfffffffff2, 3, 4, 5, 6, 7, 8);
- return 0x11;
- }
- 0x0000000000400590 <main+0>: push rbp
- 0x0000000000400591 <main+1>: mov rbp,rsp
- 0x0000000000400594 <main+4>: sub rsp,0x18
- 0x0000000000400598 <main+8>: mov DWORD PTR [rsp],0x8
- 0x000000000040059f <main+15>: mov r9d,0x7
- 0x00000000004005a5 <main+21>: mov r8d,0x6
- 0x00000000004005ab <main+27>: mov ecx,0x5
- 0x00000000004005b0 <main+32>: mov edx,0x4
- 0x00000000004005b5 <main+37>: mov esi,0x3
- 0x00000000004005ba <main+42>: mov rdi,0xfffffffff2
- 0x00000000004005c4 <main+52>: call 0x400530 <add>
- 0x00000000004005c9 <main+57>: mov DWORD PTR [rbp-8],rax
- 0x00000000004005cd <main+61>: mov eax,0x11
- 0x00000000004005d2 <main+66>: leave
- 0x00000000004005d3 <main+67>: ret
- (gdb) nexti
- 0x00000000004005c4 in main ()
- (gdb) info reg rsp
- rsp 0x7fffffffeaf8 0x7fffffffeaf8
- (gdb) nexti
- Breakpoint 2, 0x0000000000400534 in add ()
- (gdb) info reg rsp
- rsp 0x7fffffffeae8 0x7fffffffeae8
- (gdb) x /3xg 0x7fffffffeae8
- 0x7fffffffeae8: 0x00007fffffffeb10 0x00000000004005c9
- 0x7fffffffeaf8: 0x0000000000000008
- (gdb)