39 C 语言与汇编语言混合编程

参考

https://blog.51cto.com/13475106/category6.html及狄泰软件相关课程

 

从下图的编译过程就可以很明显的看出可执行文件的生成过程

 

 

 

编译小知识
1.源文件编译后得到目标文件-二进制文件
2.不同语言可编译相同格式的目标文件
3.链接器负责将目标文件组装得到可执行文件

在这里出现的一个问题-C语言中的函数调用是如何进行的?
在这里需要对函数调用时栈的变化进行解释

 

 

 

ebp指向关键位置上半部分-高地址位置,包含了函数调用之前的信息,下部分低地址处函数调用后所使用的信息。
汇编语言栈的变化-执行入栈出栈的操作
C语言函数调用(如上图所示)-ebp指向当前栈顶,esp指向的也是栈顶,当函数返回时,将函数所使用堆空间释放,将栈顶指针寄存器位置改变,做法是将esp移动到基准位置ebp位置,之后ebp恢复之前的值(将其弹出)

,此时esp指向的是返回地址,结束之后esp指向参数的位置,在这里需要介绍调用约定的概念

 

调用约定

1.参数从右到左入栈
2.函数调用者负责参数的入栈出栈
3.函数本身根据约定使用栈中参数

 

 

GCC编译器使用的栈帧布局

 

 ebp是函数调用以及函数返回的核心寄存器
1.ebp寄存器位当前栈帧的基准
2.通过ebp能够获取返回值地址、参数、局部变量等

 

 

 在接下来的会用实验来进行验证

 

使用汇编语言编写Linux可执行程序

a.定义_start标签作为程序执行的起点
b.通过int 0x80使用内核服务(执行系统调用)

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
global _start ;标签 程序入口处
 
[section .data]
    vstr    db  "D.T.Software",0x0A
 
[section .text]
_start:     ;app entry
    mov edx,13
    mov ecx,vstr   ;"D.T.Software\n"
    mov ebx,1
    mov eax,4    ;sys_write
    int 0x80  
 
    mov ebx,0 
    mov eax,1  ;sys_exit
    int 0x80

交互关键字
1.global-从汇编语言中导出符号(变量或函数)
2.extern-使用外部文件中定义的符号(变量或函数)

示例分析

 

 实验运行结果-在linux下编程

 

 混合编程注意事项
1.相同的目标文件格式--elf格式
2.相同的函数调用约定--cdecl调用约定
3.相同的活动记录(栈帧)结构-ebp基准

实验

代码-新建entry.asm、main.c、test.c
代码分别为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
;entry.asm
global _start
global vstr
global vlen
global print
 
extern c_func
 
[section .data]
   vstr    db    "D.T.Software", 0x0A
   vlen    dd    $ - vstr
 
[section .text]
_start:
    mov ebp, 0
 
    call c_func
 
    call exit
 
print:
    push ebp
    mov ebp, esp
 
    mov edx, [ebp + 12]
    mov ecx, [ebp + 8]
    mov ebx, 1
    mov eax, 4
    int 0x80
 
    pop ebp
    ret
 
exit:
    mov ebx, 0
    mov eax, 1
    int 0x80
 
main.c     
extern void print(char*, int len);
extern char vstr[];
extern int vlen;
 
int c_func()
{
    char* delphi = "Delphi\n";
 
    print(vstr, vlen);
 
    return 0;
}
 
test.c
 
extern void print(char*, int len);
extern char vstr[];
extern int vlen;
 
int c_func()
{
    char* delphi = "Delphi\n";
 
    print(vstr, vlen);
 
    return 0;
}

 运行结果-c语言与汇编
在这里需要使用gcc将其编译成目标文件,最后进行链接

 

 

小结

C语言与汇编语言在满足以下条件时可以混合编程
1.遵循相同的函数调用约定
2.遵循相同的目标文件格式

 

 

 

  

posted on   lh03061238  阅读(328)  评论(0编辑  收藏  举报

编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示