HelloWorld

ASM,C,LUA,LINUX(gentoo)
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

汇编函数调用的参数传递

Posted on 2011-10-07 17:58  光铭  阅读(4622)  评论(0编辑  收藏  举报

32bit 汇编函数调用参数传递是通过堆栈来实现的。

 1 .section .data
2 output:
3 .asciz "The processor Vendor ID is %s\n"
4 .section .bss
5 .lcomm buffer,12
6 .section .text
7 .globl main
8 main:
9 movl $0,%eax
10 cpuid
11 movl $buffer, %edi
12 movl %ebx, (%edi)
13 movl %edx, 4(%edi)
14 movl %ecx, 8(%edi)
15 pushl $buffer #第二个参数先进栈,第一个后进栈,这样pop的时候第一个就会先出来,反正就是参数从右到左进栈
16 pushl $output
17 call printf
18 addl $8, %esp #前面push了现在要堆栈平衡
19 pushl $0
20 call exit

64bit的参数传递会首先用到寄存器,寄存器不够,才用对堆栈

LINUX下面INTERGER参数(包括bool,char,short,int,long,long long)从左到右依次放到寄存器%rdi,%rsi,%rdx,%rcx,%r8,%r9,超过6个放堆栈里;SSE型的参数(float,double),从左到右依次放到vector registers(%xmm0-%xmm7)

注意%rax的作用

1)temporary register;
2)with variable arguments passes information about the number of vector registers used;
3)1st return register
特别注意第二点
For calls that may call functions that use varargs or stdargs (prototype-lesscalls or calls to functions containing ellipsis (. . . ) in the declaration) %al is usedas hidden argument to specify the number of vector registers used.
对于变长参数的函数,要用%al指明用到的vector registers(存放float,double等类型)的个数 ,比如printf

 1 .section .data
2 output:
3 .asciz "The processor Vendor ID is %s\n"
4 .section .bss
5 .lcomm buffer, 12
6 .section .text
7 .globl main
8 main:
9 movl $0,%eax
10 cpuid
11 movl $buffer,%edi
12 movl %ebx,(%edi)
13 movl %edx,4(%edi)
14 movl %ecx,8(%edi)
15 movq $output,%rdi
16 movq $buffer,%rsi
17 movq $0,%rax #没有用到vector registers,所以%al是0
18 call printf
19 mov $0,%ax #这里的ax是返回值
20 call exit

 


Windows下面INTERGER参数从左到右依次放到rcx,rdx,r8,r9,超过4个放堆栈里,由于现在不搞windows,这个就不说了