<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                [TOC] ## 概述 我使用AT&T的規范,在linux上完成 C和匯編的互相調用,并使用gcc編譯成可執行文件。 目標:匯編函數提供輸出。類似C語言的函數 ```C void hello_world(char* value) { printf(value); } ``` 提供給C語言調用: ```C int main() { hello_world("hello world!\n"); } ``` ## 搭建AT&T的環境 * ubuntu16.04 或 ubuntu18.04 * vscode * 文件后綴: .s * gcc 下載`vscode`插件`GNU Assembler Language Support` ## C代碼生成為匯編代碼 提供一個hello.c ``` void hello_world(char* value) { printf(value); } int main() { hello_world("Hello World!\n"); } ``` 為了達到使用C++調用匯編函數輸出`hello world!`的目的,我們需要把`hello_world`函數轉化為匯編語言編寫,我們先將 gcc 將hello.c轉化為匯編代碼 ``` gcc -S hello.c -o hello.s ``` 轉化之后的匯編代碼: ``` .file "hello.c" .text .globl hello_world .type hello_world, @function hello_world: .LFB0: .cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp .cfi_def_cfa_register 6 subq $16, %rsp movq %rdi, -8(%rbp) movq -8(%rbp), %rax movq %rax, %rdi movl $0, %eax call printf nop leave .cfi_def_cfa 7, 8 ret .cfi_endproc .LFE0: .size hello_world, .-hello_world .section .rodata .LC0: .string "Hello World!\n" .text .globl main .type main, @function main: .LFB1: .cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp .cfi_def_cfa_register 6 movl $.LC0, %edi call hello_world movl $0, %eax popq %rbp .cfi_def_cfa 7, 8 ret .cfi_endproc .LFE1: .size main, .-main .ident "GCC: (Ubuntu 5.4.0-6ubuntu1~16.04.12) 5.4.0 20160609" .section .note.GNU-stack,"",@progbits ``` 我們根據上面的匯編代碼可以看到匯編的`hello_world`匯編函數。我們可以根據自己的理解重新寫一份,步驟如下: * 在C中調用hello_world匯編函數,需要先聲明: ``` extern hello_world(char* value); ``` * 編寫AT&T規范的匯編代碼,文件后綴是`.s` ## hello_world 匯編函數 hello.s ```asm #hello.s .globl hello_world .type hello_world, @function .section .text hello_world: pushq %rbp #壓棧 movq %rsp, %rbp #把棧頂指針賦值給%rbp subq $8, %rsp #調整棧指針,向下移動8個字節,給局部變量留出空間 movq %rdi, -8(%rbp) #把rdi的值賦值給位于rbp-8的局部變量 rdi代表第一個參數 movq -8(%rbp), %rax #把位于rbp-8的局部變量賦值給rax #movq %rax, %rdi #rax 賦值給 rdi movq $0, %rax #以0結尾 nop call printf leave ret ``` * 壓棧和把棧頂指針賦值給%rbp是匯編函數的常規操作,基本上每個匯編函數都需要。 * 調整棧指針,給局部變量留出空間 * `%rdi`代表是第一個參數 * 最后字符串結尾需要加上`0` * `call printf`調用printf函數打印寄存器中的字符串 hello.c ```C extern void hello_world(char* value); int main() { hello_world("Hello World!\n"); } ``` 編譯成可執行文件 ```shell $ gcc -o hello hello.c hello.s ``` 運行 ``` $ ./hello Hello World! ``` ## x64 在x64匯編中調用函數時,以下寄存器用作參數。 嘗試將它們提交到內存中,因為將來您會經常使用它們 ``` 第一個參數:RDI 第二個參數:RSI 第三個參數:RDX 第四個參數:RCX 第五個參數:R8 第六個參數:R9 ```
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看