最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C/C++ 函數(shù)原理傳參示例詳解

 更新時(shí)間:2022年12月07日 15:02:29   作者:amjieker  
這篇文章主要為大家介紹了C/C++ 函數(shù)原理傳參示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

x84-64的寄存器

本文所用gccx86-64 gcc 10.1

wiki.cdot.senecacollege.ca/wiki/X86_64…

rax - register a extended

rbx - register b extended

rcx - register c extended

rdx - register d extended

rbp - register base pointer (start of stack)

rsp - register stack pointer (current location in stack, growing downwards)

rsi - register source index (source for data copies)

rdi - register destination index (destination for data copies)

其他寄存器: r8 r9 r10 r11 r12 r13 r14 r15

函數(shù)是個(gè)什么東西?

一個(gè)簡(jiǎn)單的函數(shù)

int func(){}
int main() {
    int x = 2;
    func();
}
main:
        pushq   %rbp
        movq    %rsp, %rbp
        subq    $16, %rsp
        movl    $2, -4(%rbp)
        call    func()
        movl    $0, %eax
        leave
        ret

分配空間動(dòng)作如下所示:

這里加了個(gè)函數(shù)調(diào)用是因?yàn)樵谟行r(shí)候,沒有函數(shù)調(diào)用,就不會(huì)使用subq $16, %rsp 這一條指令,我的猜想是既然你都是棧頂?shù)?,并且不?huì)再有rbp的變化,那么棧頂以上的元素我都可以隨便用。
并且我們觀察可以得知,分配??臻g時(shí),他是分配的16個(gè)字節(jié),也就是說,有對(duì)齊
返回時(shí),彈出棧頂,就可以恢復(fù)到上一個(gè)棧幀的狀態(tài)了。

傳參姿勢(shì)

入棧規(guī)則

c/c++ 中規(guī)定的函數(shù)壓棧順序是從右到左,當(dāng)然,如果你是 Visual C/C++的話,它們有更多的玩法 比如:

template<typename T>
T val(T t) {
  cout << t << endl;
  return t;
}
signed main() {
  printf("%d%d%d", val(1), val(2), val(3));
  return 0;
}

結(jié)果

3
2
1
123

看看匯編

int func(int x, int y, int z) {
  return 0;
}
int main() {
  func(1, 2, 3);
}

生成的匯編

func(int, int, int):
        pushq   %rbp
        movq    %rsp, %rbp
        movl    %edi, -4(%rbp)
        movl    %esi, -8(%rbp)
        movl    %edx, -12(%rbp)
        movl    $0, %eax
        popq    %rbp
        ret
main:
        pushq   %rbp
        movq    %rsp, %rbp
        movl    $3, %edx
        movl    $2, %esi
        movl    $1, %edi
        call    func(int, int, int)
        movl    $0, %eax
        popq    %rbp
        ret

上文中可以看出,也證實(shí)了我們所觀察到的,首先把3傳給了edx,2傳給了esi,1傳給了edi

全都存寄存器嗎?

寄存器畢竟少,當(dāng)然,還可以存在棧上嘛

int fun() {return 0;}
int func(int x, int y, int z, int a, int b, int c, int d, int e, int f){
    fun();
    return e;
}
int main() {
    func(1, 2, 3, 4, 5, 6, 7, 8, 9);
    return 0;
}
fun():
        pushq   %rbp
        movq    %rsp, %rbp
        movl    $0, %eax
        popq    %rbp
        ret
func(int, int, int, int, int, int, int, int, int):
        pushq   %rbp
        movq    %rsp, %rbp
        subq    $24, %rsp
        movl    %edi, -4(%rbp)
        movl    %esi, -8(%rbp)
        movl    %edx, -12(%rbp)
        movl    %ecx, -16(%rbp)
        movl    %r8d, -20(%rbp)
        movl    %r9d, -24(%rbp)
        call    fun()
        movl    24(%rbp), %eax
        leave
        ret
main:
        pushq   %rbp
        movq    %rsp, %rbp
        pushq   $9  // 24+%rbp
        pushq   $8  // 16+%rbp
        pushq   $7  // 8 +%rbp
        movl    $6, %r9d
        movl    $5, %r8d
        movl    $4, %ecx
        movl    $3, %edx
        movl    $2, %esi
        movl    $1, %edi
        call    func(int, int, int, int, int, int, int, int, int)
        addq    $24, %rsp
        movl    $0, %eax
        leave
        ret

主函數(shù)中的這三條語句

pushq   $9
pushq   $8
pushq   $7

說明了,當(dāng)函數(shù)入棧放寄存器放不下時(shí),會(huì)放在棧上,放在棧頂之上,等函數(shù)調(diào)用執(zhí)行完成后,rbp取出回到當(dāng)前位置之后,再去addq $24, %rsp 把棧彈出這些元素。

并且func函數(shù)中的movl 24(%rbp), %eax也證明了,傳的參數(shù)是在棧頂?shù)纳厦妫ㄗ陨舷蛳略鲩L(zhǎng)) 24 + %rbp 剛好是 $9, 也就是局部變量f的位置

傳對(duì)象呢?

在這里,暫且不談內(nèi)存布局,把一個(gè)對(duì)象看成一塊內(nèi)存對(duì)于的位置
這里用一個(gè)結(jié)構(gòu)體做示例

struct E {int x, y, z;};
E func(E e){
    e.x = 2;
    return e;
}
int main() {
    E e = {.x = 1, .y = 2, .z = 3};
    e = func(e);
    return 0;
}
func(E):
        pushq   %rbp
        movq    %rsp, %rbp
        // 將rdi 和 esi 取出來 放到 rdx 和 eax 中
        movq    %rdi, %rdx
        movl    %esi, %eax
        // 存放到開辟好的空間中 {x = rbp - 32, y = rbp - 28, z = rbp - 24}
        movq    %rdx, -32(%rbp)
        movl    %eax, -24(%rbp)
        // 更改 x
        movl    $2, -32(%rbp)
        // 將值移動(dòng)到寄存器上,從返回寄存器上移動(dòng)到局部返回出去的變量
        movq    -32(%rbp), %rax
        movq    %rax, -12(%rbp)
        movl    -24(%rbp), %eax
        movl    %eax, -4(%rbp)
        // 將返回值值移動(dòng)到寄存器上 rax rdx 上
        movq    -12(%rbp), %rax
        movl    -4(%rbp), %ecx
        movq    %rcx, %rdx
        popq    %rbp
        ret
main:
        // 壓棧保存現(xiàn)場(chǎng) 沒什么好說的
        pushq   %rbp
        movq    %rsp, %rbp
        subq    $16, %rsp
        // 內(nèi)存布局
        rbp
        | z  rbp - 4  
        | y  rbp - 8
        | x  rbp - 12
        movl    $1, -12(%rbp)
        movl    $2, -8(%rbp)
        movl    $3, -4(%rbp)
        // 移動(dòng) x 和 y 到 rdx 寄存器中
        movq    -12(%rbp), %rdx
        // 移動(dòng) z 到 eax中
        movl    -4(%rbp), %eax
        // 再將 rdx 和 eax 分別移動(dòng)到rdi 和 esi中
        movq    %rdx, %rdi
        movl    %eax, %esi
        call    func(E)
        // 從rax 中取出x y
        movq    %rax, -12(%rbp)
        // 從rdx中取出z
        movl    -4(%rbp), %eax
        andl    $0, %eax
        orl     %edx, %eax //
        movl    %eax, -4(%rbp)
        movl    $0, %eax
        leave
        ret

以上就是C/C++ 函數(shù)原理傳參示例詳解的詳細(xì)內(nèi)容,更多關(guān)于C/C++ 函數(shù)原理傳參的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 從頭學(xué)習(xí)C語言之if語句的使用

    從頭學(xué)習(xí)C語言之if語句的使用

    這篇文章主要為大家詳細(xì)介紹了C語言之if語句的使用,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-01-01
  • linux之sort命令的用法

    linux之sort命令的用法

    sort將文件的每一行作為一個(gè)單位,相互比較,比較原則是從首字符向后,依次按ASCII碼值進(jìn)行比較,最后將他們按升序輸出
    2013-10-10
  • C語言的循環(huán)小練習(xí)詳解

    C語言的循環(huán)小練習(xí)詳解

    這篇文章主要為大家介紹了C語言的循環(huán)小練習(xí),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-01-01
  • 一文掌握 C++ 智能指針的使用方法

    一文掌握 C++ 智能指針的使用方法

    C++11 引入了智能指針的概念,使用了引用計(jì)數(shù)的想法,讓程序員不再需要關(guān)心手動(dòng)釋放內(nèi)存。關(guān)于C++指針得內(nèi)容下面文章將為大家做一個(gè)詳細(xì)介紹
    2021-09-09
  • C語言實(shí)現(xiàn)簡(jiǎn)單的井字棋游戲

    C語言實(shí)現(xiàn)簡(jiǎn)單的井字棋游戲

    這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)簡(jiǎn)單的井字棋游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-04-04
  • C語言函數(shù)指針的老生常談

    C語言函數(shù)指針的老生常談

    這篇文章主要為大家介紹了vue組件通信的幾種方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2021-11-11
  • 深入理解C++的對(duì)象模型

    深入理解C++的對(duì)象模型

    本文在介紹C++使用的對(duì)象模型之前,先介紹了2種對(duì)象模型:簡(jiǎn)單對(duì)象模型(a simple object model)和表格驅(qū)動(dòng)對(duì)象模型(a table-driven object model),這樣介紹對(duì)后面的內(nèi)容更有幫助,有需要的小伙伴們可以參考學(xué)習(xí)。
    2016-08-08
  • C++ 動(dòng)態(tài)創(chuàng)建按鈕及 按鈕的消息響應(yīng)

    C++ 動(dòng)態(tài)創(chuàng)建按鈕及 按鈕的消息響應(yīng)

    這篇文章主要介紹了C++ 動(dòng)態(tài)創(chuàng)建按鈕及 按鈕的消息響應(yīng)的相關(guān)資料,需要的朋友可以參考下
    2015-06-06
  • C語言中循環(huán)嵌套的應(yīng)用方式

    C語言中循環(huán)嵌套的應(yīng)用方式

    這篇文章主要介紹了C語言中循環(huán)嵌套的應(yīng)用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • C語言中等待socket連接和對(duì)socket定位的方法

    C語言中等待socket連接和對(duì)socket定位的方法

    這篇文章主要介紹了C語言中等待socket連接和對(duì)socket定位的方法,分別為listen()函數(shù)和bind()函數(shù)的用法,需要的朋友可以參考下
    2015-09-09

最新評(píng)論

湘西| 徐州市| 运城市| 衡阳县| 台东县| 双辽市| 石家庄市| 徐汇区| 长乐市| 甘孜县| 比如县| 西宁市| 精河县| 白山市| 景宁| 张家港市| 余姚市| 浦县| 房山区| 门头沟区| 衡山县| 九龙县| 两当县| 运城市| 临夏市| 安达市| 枝江市| 扬中市| 焉耆| 凤庆县| 龙门县| 永昌县| 漠河县| 丰都县| 扎囊县| 山东省| 历史| 泽州县| 浙江省| 丰原市| 康保县|