首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> 關於C

C 與彙編混合編程:相互調用原理、構建流程與完整實例

     編輯:關於C

核心原理:編譯鏈接階段的符號解析

C 與彙編能相互調用的本質:兩者編譯產生相同格式的目標文件(.o),鏈接器將符號引用解析為地址。

  1. 編譯:gcc -c bar.c -o bar.o、nasm -f elf foo.asm -o foo.o — 產生含符號表、重定位表的目標文件
  2. 鏈接:ld -m elf_i386 -o foobar foo.o bar.o — 將 foo.o 中 extern choose 與 bar.o 中 int choose(int,int) 符號匹配,重定位為最終地址

完整實例:彙編主程序調用 C 函數,C 函數回調彙編打印函數

foo.asm (NASM 語法,32 位 ELF)

section .data
    num1st  dq 3
    num2nd  dq 4

section .text
    extern choose          ; 声明 C 函數
    global main
    global myprint         ; 導出彙編函數供 C 調用

main:
    push dword [num2nd]    ; 參數壓棧:右到左
    push dword [num1st]
    call choose            ; 調用 C 函數
    add esp, 8             ; 清理參數棧

    mov ebx, 0             ; exit(0)
    mov eax, 1
    int 0x80

; 彙編實現的打印函數:void myprint(char *msg, int len)
myprint:
    mov edx, [esp+8]       ; len
    mov ecx, [esp+4]       ; msg
    mov ebx, 1             ; stdout
    mov eax, 4             ; sys_write
    int 0x80
    ret

bar.c

#include 

extern void myprint(char *msg, int len);  // 彙編函數聲明

int choose(int a, int b) {
    if (a >= b) {
        myprint("the 1st one", 13);
    } else {
        myprint("the 2nd one", 13);
    }
    return 0;
}

構建腳本

#!/bin/bash
# build.sh
gcc -m32 -c -o bar.o bar.c
nasm -f elf32 -o foo.o foo.asm
ld -m elf_i386 -s -o foobar foo.o bar.o
./foobar

運行結果

the 1st one

關鍵技術點總結

項目說明
調用約定32 位 cdecl:參數右向左壓棧,調用者清棧,返回值在 EAX
符號修飾C 編譯器不修飾函數名(_cdecl),彙編直接用原名 extern/global
數據訪問彙編用 [esp+offset] 訪問棧參數;C 結構體布局需與彙編定義一致
系統調用Linux x86 用 int 0x80,eax 為調用號(1=exit, 4=write)
64 位差異參數用寄存器 (RDI, RSI, RDX, RCX, R8, R9),syscall 指令,調用號不同

調試技巧

# 查看符號表
nm bar.o foo.o

# 反彙編可執行文件
objdump -d -M intel foobar

# GDB 混合調試
gdb ./foobar
(gdb) break choose
(gdb) break myprint
(gdb) run
(gdb) info registers
(gdb) x/10i $pc

總結

C 與彙編混合編程的關鍵在於統一調用約定、正確聲明符號、鏈接階段解析地址。掌握此技術,可在性能熱點用彙編優化、對接裸機硬件、分析編譯器生成代碼、編寫啟動代碼/中斷處理等場景發揮關鍵作用。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved