ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

X86汇编层面的方法调用。

2022-08-20 23:31:49  阅读:179  来源: 互联网

标签:汇编 movl 调用 X86 int rbp eax test edx


本文主要描述了X64下的汇编层面的方法调用。具体来说就是一个C语言的方法被另外一个方法调用,是如果在汇编语言X64的规范中实现的。

1.假设有如下C语言文件 "test.c"

点击查看代码
int sumNine(int one, int two, int three, int four, int five, 
          int six, int seven, int eight, int nine) 
{ 
    int x;  
	x = one + two + three + four + five + six + seven + 
	eight + nine; 
    return x; 
}


int main(void) 
{ 
    int total; 
    int a = 1; 
    int b = 2; 
    int c = 3; 
    int d = 4; 
    int e = 5; 
    int f = 6; 
    int g = 7; 
    int h = 8; 
    int i = 9; 
    total = sumNine(a, b, c, d, e, f, g, h, i); 
    return 0; 
}

2.通过GCC 命令 "gcc -o test.s -fverbose-asm -S -O0 -g test.c" 查看生成的汇编语言

点击查看代码
main:
        endbr64
        pushq   %rbp    #
        movq    %rsp, %rbp      #,
        subq    $48, %rsp       #,
# test.c:14:     int a = 1;
        movl    $1, -40(%rbp)   #, a
# test.c:15:     int b = 2;
        movl    $2, -36(%rbp)   #, b
# test.c:16:     int c = 3;
        movl    $3, -32(%rbp)   #, c
# test.c:17:     int d = 4;
        movl    $4, -28(%rbp)   #, d
# test.c:18:     int e = 5;
        movl    $5, -24(%rbp)   #, e
# test.c:19:     int f = 6;
        movl    $6, -20(%rbp)   #, f
# test.c:20:     int g = 7;
        movl    $7, -16(%rbp)   #, g
# test.c:21:     int h = 8;
        movl    $8, -12(%rbp)   #, h
# test.c:22:     int i = 9;
        movl    $9, -8(%rbp)    #, i
# test.c:23:     total = sumNine(a, b, c, d, e, f, g, h, i);
        movl    -20(%rbp), %r9d # f, tmp84
        movl    -24(%rbp), %r8d # e, tmp85
        movl    -28(%rbp), %ecx # d, tmp86
        movl    -32(%rbp), %edx # c, tmp87
        movl    -36(%rbp), %esi # b, tmp88
        movl    -40(%rbp), %eax # a, tmp89

		pushq   %rdi    # tmp90
        movl    -12(%rbp), %edi # h, tmp91
        pushq   %rdi    # tmp91
        movl    -16(%rbp), %edi # g, tmp92
        pushq   %rdi    # tmp92
        movl    %eax, %edi      # tmp89,
        call    sumNine #

        addq    $24, %rsp       #,
        movl    %eax, -4(%rbp)  # tmp93, total
# test.c:24:     return 0;
        movl    $0, %eax        #, _13
# test.c:25: }
        leave
        ret

sumNine: 
        pushq  %rbp 
        movq  %rsp, %rbp 
        subq  $48, %rsp 
        movl  %edi, -20(%rbp)  # save one 
        movl  %esi, -24(%rbp)  # save two 
        movl  %edx, -28(%rbp)  # save three 
        movl  %ecx, -32(%rbp)  # save four 
        movl  %r8d, -36(%rbp)  # save five 
        movl  %r9d, -40(%rbp)  # save six 
        movl  -24(%rbp), %eax  # load two 
        movl  -20(%rbp), %edx  # load one, subtotal 
        addl  %eax, %edx       # add two to subtotal 
        movl  -28(%rbp), %eax  # load three 
        addl  %eax, %edx       # add to subtotal 
        movl  -32(%rbp), %eax  # load four 
        addl  %eax, %edx       # add to subtotal 
        movl  -36(%rbp), %eax  # load five 
        addl  %eax, %edx       # add to subtotal 
        movl  -40(%rbp), %eax  # load six 
        addl  %eax, %edx       # add to subtotal 
        movl  16(%rbp), %eax   # load seven 
        addl  %eax, %edx       # add to subtotal 
        movl  24(%rbp), %eax   # load eight 
        addl  %eax, %edx       # add to subtotal 
        movl  32(%rbp), %eax   # load nine 
        addl  %edx, %eax       # add to subtotal 
        movl  %eax, -4(%rbp)   # x <- total
        movl  $.LC0, %edi 
        call  puts 
        movl  -4(%rbp), %eax 
        leave 
        ret 


Main函数中allocate了48个字节作为local variable的空间。
在调用sumNine的时候,前面6个需要传输的参数通过设置指定的Register来传输数据[2],多余的3个参数通过插入当前stack的形式来传输数据。(但是这边很奇怪的是48 + 3 * 8 = 72字节,stack pointer (rsp) 并没有16字节对齐,有知道的小伙伴告诉我一下为啥没有16字节对齐也能work)。在被调用的函数中前面6个传输通过register中获取,后面3个参数通过stack来获取。在调用sumNine的时候的Stack如下图所示。所有的参数都是通过8字节传输,并且在最后在stack中插入返回地址。
image
当调用到sumNine里面的时候, stack的样子设置如下。可以通过(rbp+16)拿到传入到函数中的参数,注意stack中包含了Return Address 和 Caller's rbp,所以需要加16才能拿到数据。
image

Summary

方法间的调用的时候,是通过Register和Stack传输数据的。并且需要返回的地址也会在调用函数的时候被插入。在调用其他函数之前 rbp 和 rsp 之间的数据存放着local variable 和 需要调用其他函数的参数。

Reference

[1] https://bob.cs.sonoma.edu/IntroCompOrg-x64/bookch11.html#x31-13800011

[2]image
[3]image

标签:汇编,movl,调用,X86,int,rbp,eax,test,edx
来源: https://www.cnblogs.com/robsann/p/16608689.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有