[zz]asmlinkage & regparm

发信人: feiy (积极、乐观、率性、自信), 信区: KernelTech
标  题: asmlinkage 其他 regparm attribute函数的gcc汇编浅析
发信站: BBS 水木清华站 (Mon Apr 26 02:56:12 2004), 转信

[asmlinkage 其他 regparm attribute函数的gcc汇编浅析]

asmlinkage是一类特殊的regparm attribute函数:
#define asmlinkage CPP_ASMLINKAGE __attribute__((regparm(0)))

下面的分析基于:c 源码 tt.c, 汇编代码 tt.S, shell命令是
gcc -S tt.c -o tt.S  gcc version 3.2.2, cpu 386+

1. C 源码

01__attribute__((regparm(0~3))) int cal(int a, int b, int c, int d)
02{
03return a + b + c + d;
04}
05int main()
06{
07int  r1=1;
08int  r2=2;
09int  r3=3;
10int  r4=4;
11 
12cal(r1, r2, r3, r4);
13 
14return 0;
15}

2. 当__attribute__((regparm(0))) int cal(int a, int b, int c, int d)
gcc编译得到下述汇编代码

01.file    "tt.c"
02.text
03.globl cal
04.type    cal,@function
05cal:
06pushl   %ebp
07movl    %esp,     %ebp
08movl    12(%ebp), %eax  # 从 堆栈 中取出传递给函数的第二个参数 b
09addl    8(%ebp),  %eax  # 从 堆栈 中取出传递给函数的第一个参数 a
10addl    16(%ebp), %eax  # 从 堆栈 中取出传递给函数的第三个参数 c
11addl    20(%ebp), %eax  # 从 堆栈 中取出传递给函数的第四个参数 d
12leave
13ret
14.Lfe1:
15.size    cal,.Lfe1-cal
16.globl main
17.type    main,@function
18main:
19pushl    %ebp
20movl    %esp, %ebp
21subl    $24, %esp
22andl    $-16, %esp
23movl    $0, %eax
24subl    %eax, %esp
25movl    $1, -4(%ebp)
26movl    $2, -8(%ebp)
27movl    $3, -12(%ebp)
28movl    $4, -16(%ebp)
29pushl   -16(%ebp)       # 参数通过堆栈传递, 把要传递给函数的第四个参数压栈
30pushl   -12(%ebp)       # 第三个参数入栈  注:这里的ebp用来指示main函数的局
31pushl   -8(%ebp)        # 第二个参数入栈     部变量,-4(%ebp)存放的是第一
32pushl   -4(%ebp)        # 第一个参数入栈     个局部变量r1,-4属于分配上的
33call    cal             #                  巧合, 这里的-4与r1将作为传递给函
34#                  数的第一个参数没有必然的关系。
35addl    $16, %esp
36movl    $0, %eax
37leave
38ret
39.Lfe2:
40.size    main,.Lfe2-main
41.ident    "GCC: (GNU) 3.2.2 20030222 (Red Hat Linux 3.2.2-5)"

3. 当__attribute__((regparm(3))) int cal(int a, int b, int c, int d)
得到下述汇编代码

01.file    "tt.c"
02.text
03.globl cal
04.type    cal,@function
05cal:
06pushl    %ebp
07movl    %esp, %ebp
08subl    $12, %esp
09movl    %eax, -4(%ebp)  # 从 %eax 中取出传递给函数的第一个参数 a
10movl    %edx, -8(%ebp)  # 从 %edx 中取出传递给函数的第二个参数 b
11movl    %ecx, -12(%ebp) # 从 %ecx 中取出传递给函数的第三个参数 c
12movl    -8(%ebp), %eax
13addl    -4(%ebp), %eax
14addl    -12(%ebp), %eax
15addl    8(%ebp), %eax   # 从 堆栈 中取出传递给函数的第四个参数 d
16leave
17ret
18.Lfe1:
19.size    cal,.Lfe1-cal
20.globl main
21.type    main,@function
22main:
23pushl    %ebp
24movl    %esp, %ebp
25subl    $24, %esp
26andl    $-16, %esp
27movl    $0, %eax
28subl    %eax, %esp
29movl    $1, -4(%ebp)
30movl    $2, -8(%ebp)
31movl    $3, -12(%ebp)
32movl    $4, -16(%ebp)
33subl    $12, %esp
34movl    -12(%ebp), %ecx   # 通过 ecx  向函数传递第三个参数 r3
35movl    -8(%ebp), %edx    # 通过 edx  向函数传递第二个参数 r2
36movl    -4(%ebp), %eax    # 通过 eax  向函数传递第一个参数 r1
37pushl    -16(%ebp)        # 通过 堆栈 向函数传递第四个参数 r4
38call    cal
39addl    $16, %esp
40movl    $0, %eax
41leave
42ret
43.Lfe2:
44.size    main,.Lfe2-main
45.ident    "GCC: (GNU) 3.2.2 20030222 (Red Hat Linux 3.2.2-5)"

4. 结论

1) __attribute__((regparm(0~3))) 用来指定函数调用时通过寄存器传递参
数的个数

2) if any, 从第一个参数起, 依此通过 eax, edx, ecx 传递参数,

3) 而多出的参数将通过堆栈传递. 堆栈传递总是最后一个先入栈.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值